package org.apli.haiam.admin.jsf.managed;

import com.apli.controladores.Aplinfo;
import com.apli.controladores.AplinfoFactoryBean;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.model.DataModel;
import javax.faces.model.SelectItem;
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import org.apli.haiam.admin.entidades.UsuarioAdmin;
import org.apli.haiam.ejb.entidades.AdmDatosGlobales;
import org.apli.haiam.ejb.entidades.AdmDivisionPolitica;
import org.apli.haiam.ejb.entidades.AdmPermiso;
import org.apli.haiam.ejb.entidades.AdmTipoConsulta;
import org.apli.haiam.ejb.entidades.AdmUsuario;
import org.apli.haiam.ejb.entidades.CexAgenda;
import org.apli.haiam.ejb.entidades.CexDia;
import org.apli.haiam.ejb.entidades.CexEspecialidad;
import org.apli.haiam.ejb.entidades.CexEspecialidadMedico;
import org.apli.haiam.ejb.entidades.CexHistoriaClinica;
import org.apli.haiam.ejb.entidades.CexHorario;
import org.apli.haiam.ejb.entidades.CexHorariosDia;
import org.apli.haiam.ejb.entidades.CexPreparacion;
import org.apli.haiam.ejb.interfaces.AdministradorHaiam;
import org.apli.haiam.ejb.interfaces.ConsExternaAdministrador;
import org.apli.jsf.managed.JsfBean;
import org.primefaces.event.RowEditEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Clase backing Bean que administra la entidad CexEspecialidadMedico.
 * <p>
 * <H6>Soporte:HAIAM
 * <I>david_s_1086@hotmail.com,david.carranza@haiam.gob.ec</I></H6>
 *
 * @author david Carranza
 * @version 1.0 30/07/2014
 */
@ManagedBean
@ViewScoped
public class JsfAgenda extends JsfBean<CexEspecialidadMedico> {

    final Logger log = LoggerFactory.getLogger(JsfAgenda.class);
    private CexEspecialidad especialidad;
    private CexEspecialidad subEspecialidad;
    private List<CexHorariosDia> listaHorarioDia;
    private CexHistoriaClinica hcPaciente;
    private String parametroBusqueda;
    private Integer busqueda;
    private UsuarioAdmin user;
    private Calendar horaInicioAm;
    private Calendar horaFinAm;
    private CexHistoriaClinica hcHistoria;
    private Integer tipoBusqueda;
    private String apellidoPbusqueda;
    private String apellidoMbusqueda;
    private String pnombrebusqueda;
    private String snombrePbusqueda;
    private List<AdmDatosGlobales> listaDatosGlobales;
    private List<CexHistoriaClinica> listaHClinica;
    private CexAgenda agenda;
    private Date fechaAgenda;
    private AdmDivisionPolitica provincia;
    private AdmDivisionPolitica canton;
    private AdmDivisionPolitica parroquia;
    private Boolean habilitar;
    private List<CexHorario> listaHorarioMed;
    public int cadulaInc = 0;
    private boolean activo;
    private boolean isextra;
    private List<AdmDatosGlobales> listaImpresorasturnos;
    private List<CexAgenda> listaHistorialTurnos;
    private ConsExternaAdministrador hcAdmin;
    private BigDecimal rangoMuinutos;
    private long diffMinutes;
    private boolean isGrabar;
    private int tipoAgenda;
    private Calendar c1;
    private Integer dia;
    private int totalConsulta;
    private AdmTipoConsulta admTipoConsulta;
    private AdmUsuario admUsuario;
    private List<CexDia> listaDia;
    private String motivoBloqueo;
    private String motivoCancelar;
    private List<CexAgenda> listaAgenda;
    private Date horaTurnoExtra;
    private static final String TIPO_IMPRESORAS = "IMP_TMU220D";
    private static final String NAME_REPORTE = "RPT_TURNO.jasper";
    private static final String TIPO_REPORTE_PDF = "application/pdf";
    private static final String TIPO_REPORTE_EXC = "application/vnd.ms-excel";

    // private AdmSistema sistemaSeleccionado;
    /**
     * Constructor por defecto.
     */
    public JsfAgenda() {
        // sistemaSeleccionado = new AdmSistema();
    }

    /**
     * Inicializa los datos miembros.
     */
    @Override
    protected void inicializar() {
        //setSwGrabar(false);
        object = new CexEspecialidadMedico();
        especialidad = new CexEspecialidad();
        listaHorarioDia = new ArrayList<>();
        subEspecialidad = new CexEspecialidad();
        hcPaciente = new CexHistoriaClinica();
        parametroBusqueda = new String();
        busqueda = 1;
        horaInicioAm = new GregorianCalendar();
        horaFinAm = new GregorianCalendar();
        tipoBusqueda = 2;
        hcHistoria = new CexHistoriaClinica();
        apellidoPbusqueda = new String();
        apellidoMbusqueda = new String();
        pnombrebusqueda = new String();
        snombrePbusqueda = new String();
        listaHClinica = new ArrayList<>();
        agenda = new CexAgenda();
        fechaAgenda = new Date();
        provincia = new AdmDivisionPolitica();
        canton = new AdmDivisionPolitica();
        parroquia = new AdmDivisionPolitica();
        habilitar = true;
        listaHorarioMed = new ArrayList<>();
        cadulaInc = 0;
        activo = false;
        isextra = false;
        rangoMuinutos = BigDecimal.ZERO;
        diffMinutes = 0;
        isGrabar = false;
        tipoAgenda = 0;
        c1 = Calendar.getInstance();
        dia = 0;
        totalConsulta = 0;
        listaAgenda = new ArrayList<>();
        motivoBloqueo = "";
        horaTurnoExtra = new Date();
        motivoCancelar = "";
        try {
            user = (UsuarioAdmin) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user");
            admUsuario = user.getUser();
            listaDatosGlobales = adminObject.listar(AdmDatosGlobales.class, "estado", 1);
            if (user.getUser().getAdmEmpleado().getAdmDepartamento().getIdDepartamento().equals(4)) {
                admTipoConsulta = (AdmTipoConsulta) adminObject.buscar(AdmTipoConsulta.class, "atcId", 2);
            } else if (user.getUser().getAdmEmpleado().getAdmDepartamento().getIdDepartamento().equals(2)) {
                admTipoConsulta = (AdmTipoConsulta) adminObject.buscar(AdmTipoConsulta.class, "atcId", 1);
            } else if (user.getUser().getAdmEmpleado().getAdmDepartamento().getIdDepartamento().equals(1) || !user.getUser().getAdmEmpleado().getAdmDepartamento().getIdDepartamento().equals(3)) {
                admTipoConsulta = (AdmTipoConsulta) adminObject.buscar(AdmTipoConsulta.class, "atcId", 1);
            }
            listaDia = adminObject.listar(CexDia.class, "cdiEstado", 1);
            cargarImpresoraTurnos();
        } catch (Exception e) {
            log.error("inicializar() {} ", e.getMessage());
        }

    }

    /**
     * Iyección de dependencia para conectarse al EJB(Lógica de Negocio)
     * Iyección de dependencia para el sistema de Administarción. Iyección de
     * dependencia para el sistema de Emergencia.
     */
    @Override
    protected void cargarEjb() {
        //super.cargarEjb();
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "()";
        if (hcAdmin == null) {
            String ejbPath = null;
            try {
                ResourceBundle property = getProperties();
                String ORBContext = property.getString("ORBContext");
                String ejbContextPath = property.getString("ejb.context.path.ConsExterna");
                ejbPath = ORBContext + ejbContextPath + "/ConsExternaAdministradorBean";
                hcAdmin = (ConsExternaAdministrador) AplinfoFactoryBean.lookupBean(ejbPath, false);
            } catch (Exception e) {
                log.error("{}: {} - {} ", new Object[]{nombreMetodo, ejbPath, e});
            }

        }

        if (adminObject == null) {
            String ejbPath = null;
            try {
                ResourceBundle property = getProperties();
                String ORBContext = property.getString("ORBContext");
                String ejbContextPath = property.getString("ejb.context.path.admin");
                ejbPath = ORBContext + ejbContextPath + "/AdministradorBeanHaiam";
                adminObject = (AdministradorHaiam) AplinfoFactoryBean.lookupBean(ejbPath, false);
            } catch (Exception e) {
                log.error("{}: {} - {} ", new Object[]{nombreMetodo, ejbPath, e});
            }
        }
    }

    /**
     * Carga en la lista las impresoras para la impresion de stickers
     */
    public void cargarImpresoraTurnos() {
        listaImpresorasturnos = new ArrayList<>();
        for (AdmDatosGlobales datosGlobales : listaDatosGlobales) {
            if (datosGlobales.getTipo().equals(TIPO_IMPRESORAS)) {
                listaImpresorasturnos.add(datosGlobales);
            }
        }
    }

    /**
     * Graba el registro asociado al objeto que se administra en la página.
     *
     * @return null, se mantiene en la página invocada.
     */
    @Override
    public String grabarAction() {

        FacesContext context = FacesContext.getCurrentInstance();
        try {
            int selectMult = 0;
            int contGrabar = 0;
            boolean isTurnoLibre = false;
            if (agenda.getCexHistoriaClinica() != null) {
                try {

                    //Verificar si existen turnos libre o si estan seleccionados mas de 1 turnos
                    for (CexAgenda objAgenda : listaAgenda) {
                        if (objAgenda.isSeleccionado()) {
                            selectMult = selectMult + 1;
                        }
                        if (objAgenda.getCagEstado() == 0 && objAgenda.getCagTipo() == 0) {
                            isTurnoLibre = true;
                        }
                    }

                    if (selectMult > 1) {
                        FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Se ha seleccionado mas de un turno", "Solo es permitido seleccionar un turno para agendar"));
                        return null;
                    } else if (selectMult == 0) {
                        FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "No ha seleccionado turno", "Seleccionar al menos un turno para agendar"));
                        return null;
                    }

                    if (!isTurnoLibre) {
                        FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Agenda no disponible", "No dispone de turnos libres para esta agenda"));
                        return null;
                    }
                    //Recorre la agenda del HorarioDia seleccionado
                    for (CexAgenda cexAgenda : listaAgenda) {
                        //Selecciona el objeto con estado para asignarle turbno
                        ///cexHDia.getCexAgendaList()
                        if (cexAgenda.isSeleccionado()) {
                            if ((cexAgenda.getCagEstado() == 0 && cexAgenda.getCagTipo() == tipoAgenda) || (admUsuario.getAdmEmpleado().getAdmCargo().getIdCargo().equals(0))) {
                                //Validar que el mismo paciente no tenga un mismo turno con el mismo paciente
                                if (!admin.existePorCampo(CexAgenda.class, "cexHorariosDia", cexAgenda.getCexHorariosDia(), "cexHistoriaClinica", agenda.getCexHistoriaClinica(), "cagFecha", fechaAgenda)) {
                                    //Asignar al objeto temporal el objeto de la lista seleccionado
                                    CexAgenda objAgenda = (CexAgenda) adminObject.buscar(CexAgenda.class, cexAgenda.getCagId());
                                    objAgenda.setCexHistoriaClinica(agenda.getCexHistoriaClinica());
                                    objAgenda.setCagEstado(1);
                                    objAgenda.setCagFechaRegistro(admin.getFechaDb());
                                    objAgenda.setCagHoraRegistro(objAgenda.getCagFechaRegistro());
                                    //hcAgenda.setAgeTipo(1);
                                    objAgenda.setCagIdUsuario(user.getUser().getIdUsuario().intValue());
                                    objAgenda.setCagNombreUsuario(user.getUser().getAdmEmpleado().getNombreFull());
                                    objAgenda.setCagIdInstitucion(user.getUser().getAdmEmpleado().getAdmInstitucion().getIdInstitucion());
                                    objAgenda.setCagNombreInstitucion(user.getUser().getAdmEmpleado().getAdmInstitucion().getNombre());
                                    //Verifica que no se repita el numero de turno
                                    if (!hcAdmin.existePorCampo(CexAgenda.class, "cagFecha", fechaAgenda, "cexHorariosDia", objAgenda.getCexHorariosDia(), "cagSecuencia", objAgenda.getCagSecuencia(), "cagEstado", 1)) {
                                        hcAdmin.crearTurno(objAgenda, (UsuarioAdmin) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user"));
                                        // verifica si el turno esta en base de datos
                                        print(objAgenda);
                                        FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_INFO, "Turno asignado correctamente", "Turno asignado correctamente"));
                                        break;
                                    } else {
                                        FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Turno no asignado", "Ya se encuentra un paciente asignado al turno seleccionado"));
                                        return null;
                                    }
                                } else {
                                    FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Turno no asignado", "Paciente ya tiene registrado turno con el medico seleccionado"));
                                    return null;
                                }
                            }
                        }
                    }

                } catch (Exception e) {
                    log.error("grabarAction() {} ", e.getMessage());
                    FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), e.getMessage()));
                }

            } else {
                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error Paciente", "Debe seleccionar un paciente"));
                return null;
            }

            agenda = new CexAgenda();
            tipoBusqueda = 1;
            parametroBusqueda = new String();
            //Recuperar objeto para actualizar la lista
            //Recuperar las agendas de acuerdo al horarioDia y de acuerdo a las fechas
            listaAgenda.clear();
            for (CexHorariosDia objHorDia : listaHorarioDia) {
                List<CexAgenda> listTempAgen = adminObject.listarOrdenada(CexAgenda.class, "cagFecha", fechaAgenda, "cexHorariosDia", objHorDia, "cagSecuencia", true);
                for (CexAgenda objA : listTempAgen) {
                    listaAgenda.add(objA);
                }
                listTempAgen.clear();
            }
        } catch (Exception e) {
            log.error("grabarAction() {} ", e.getMessage());

        }

        return null;
    }

    /**
     * Crea un turno extra fuera de la agenda
     *
     * @return null, se mantiene en la página invocada.
     */
    public String grabarTurnoExtra() {

        FacesContext context = FacesContext.getCurrentInstance();

        try {
            //List<CexAgenda> listT = adminObject.listar(CexAgenda.class, "cexHorariosDia", object, "ageTipo", 3, "ageEstado", 0);
            //Recorrer la lista del horarioDia
            for (CexHorariosDia cexHDia : listaHorarioDia) {
                //Recorre la agenda del HorarioDia seleccionado
                if (agenda.getCexHistoriaClinica() != null) {
                    if (!admin.existePorCampo(CexAgenda.class, "cagFecha", fechaAgenda, "cexHorariosDia", cexHDia, "cexHistoriaClinica", agenda.getCexHistoriaClinica())) {

                        try {
                            CexAgenda agendaA = new CexAgenda();
                            agendaA.setCexHistoriaClinica(agenda.getCexHistoriaClinica());
                            agendaA.setCagEstado(1);
                            agendaA.setCagTipo(2);
                            agendaA.setCagFechaRegistro(admin.getFechaDb());
                            agendaA.setCagHoraRegistro(admin.getFechaDb());
                            agendaA.setCagIdUsuario(user.getUser().getIdUsuario().intValue());
                            agendaA.setCagNombreUsuario(user.getUser().getAdmEmpleado().getNombreFull());
                            agendaA.setCagIdInstitucion(user.getUser().getAdmEmpleado().getAdmInstitucion().getIdInstitucion());
                            agendaA.setCagNombreInstitucion(user.getUser().getAdmEmpleado().getAdmInstitucion().getNombre());
                            agendaA.setCagSecuencia(100);
                            agendaA.setCagHora(horaTurnoExtra);
                            agendaA.setCagFecha(fechaAgenda);
                            agendaA.setCexHorariosDia(cexHDia);
                            adminObject.crear(agendaA, (UsuarioAdmin) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user"));
                            //////////// print(agendaA);
                            FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_INFO, "Turno asignado correctamente", "Turno asignado correctamente"));
                            break;
                        } catch (Exception e) {
                            log.error("grabarTurnoExtra() {} ", e.getMessage());
                            FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), e.getMessage()));
                        }
                    } else {
                        FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Turno extra no asignado", "Historia clínica ya tiene un turno asignado con el medico seleccionado"));
                        return null;
                    }
                } else {
                    FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Debe seleccionar un paciente", "Debe seleccionar un paciente"));
                }

            }

            agenda = new CexAgenda();
            tipoBusqueda = 1;
            parametroBusqueda = new String();
            //Recuperar objeto para actualizar la lista
            //Recuperar las agendas de acuerdo al horarioDia y de acuerdo a las fechas
            listaAgenda.clear();
            for (CexHorariosDia objHorDia : listaHorarioDia) {
                List<CexAgenda> listTempAgen = adminObject.listarOrdenada(CexAgenda.class, "cagFecha", fechaAgenda, "cexHorariosDia", objHorDia, "cagSecuencia", true);
                for (CexAgenda objA : listTempAgen) {
                    listaAgenda.add(objA);
                }
                listTempAgen.clear();
            }

        } catch (Exception e) {
            log.error("grabarTurnoExtra() {} ", e.getMessage());

        }

        return null;
    }

    /**
     * Metodo generico que crea un detalle de la agenda selecionada
     *
     * @param objAgenda
     * @author David Carranza
     * @param objHoraDia activado
     * @param act
     * @param actHorPri
     * @return
     */
    public HashMap<Integer, Date> asignarHoraSecuencia(CexAgenda objAgenda, CexHorariosDia objHoraDia, boolean act, boolean actHorPri) {
        FacesContext context = FacesContext.getCurrentInstance();
        HashMap<Integer, Date> mp = new HashMap<>();
        try {

            int contAgenda = 0;
            int intervaloTurno = objAgenda.getCexHorariosDia().getChdIntervalo();
            Calendar c3 = Calendar.getInstance();
            Integer secuencia = 0;
            boolean secNull = true;
            horaInicioAm = new GregorianCalendar();
            horaFinAm = new GregorianCalendar();
            horaInicioAm.setTime(objHoraDia.getChdHoraInicioAm());
            horaFinAm.setTime(objHoraDia.getChdHoraFinAm());

            //Calcular los tiempos para cada turno
            long iniAm = horaInicioAm.getTimeInMillis();
            long finAm = horaFinAm.getTimeInMillis();
            //calcular total de minitos al dia asignado al medico
            long totHoras = (finAm - iniAm);

            // calcular la diferencia en milisengundos
            //long diff = milis2 - milis1;
            // calcular la diferencia en segundos
            //long diffSeconds = diff / 1000;
            // calcular la diferencia en minutos
            diffMinutes = totHoras / (60 * 1000);

            // calcular la diferencia en horas
            //long diffHours = diff / (60 * 60 * 1000);
            // calcular la diferencia en dias
            //long diffDays = diff / (24 * 60 * 60 * 1000);
            rangoMuinutos = divisionControlada(new BigDecimal(diffMinutes), new BigDecimal(objHoraDia.getChdNumConsultas()));
            rangoMuinutos = rangoMuinutos.setScale(0, RoundingMode.HALF_UP);

            if (objAgenda.getCagSecuencia() == 0 && actHorPri) {
                c3.setTime(objHoraDia.getChdHoraInicioAm());
                secuencia = 1;

            } else {

                // si para cambiar de hora es cada un turno
                if (intervaloTurno == 1) {
                    if ((!act || act) && objAgenda.getCagEstado() == 0) {
                        c3.setTime(objHoraDia.getChdHoraInicioAm());
                        secuencia = totalConsulta;
                    } else {
                        //calcular (sumar) total de minitos al dia asignado al medico
                        c3.setTime(objAgenda.getCagHora());
                        c3.add(Calendar.MINUTE, rangoMuinutos.intValue());
                        secuencia = objAgenda.getCagSecuencia() + 1;
                    }

                } else {
//////////////////                    //calcular el rango de hora para cada turno
//////////////////                    BigDecimal rem = divisionControlada(new BigDecimal(diffMinutes), new BigDecimal(intervaloTurno));
//////////////////                    BigDecimal rango = rem.setScale(0, RoundingMode.HALF_UP);
//////////////////                    //Para cambiar de hora segun el numero de intervalo
//////////////////
//////////////////                    //Comparar si tiene otro valor quiere decir que debe estar con la misma horario del turno anterior
//////////////////                    if ((objAgenda.getAgeSecuencia() % intervaloTurno) == 0) {
//////////////////                        //calcular (sumar) total de minitos al dia asignado al medico
//////////////////                        c3.setTime(objAgenda.getAgeHora());
//////////////////                        c3.add(Calendar.MINUTE, rango.intValue());
//////////////////                        agenda.setAgeHora(c3.getTime());
//////////////////                    } else {
//////////////////                        c3.setTime(objAgenda.getAgeHora());
//////////////////                        agenda.setAgeHora(c3.getTime());
//////////////////                    }
//////////////////
//////////////////                    secuencia = objAgenda.getAgeSecuencia() + 1;
                }

                //secuencia = objAgenda.getAgeSecuencia() + 1;
                //c3.add(Calendar.MINUTE, rangoMuinutos.intValue());
            }
            if (!secNull) {
                secuencia = null;
            }
            mp.put(secuencia, c3.getTime());
        } catch (Exception e) {
            log.error("{}: {} ", "asignarHoraSecuencia", e);
        }
        return mp;
    }

    /**
     * Metodo generico que crea un detalle de la agenda selecionada
     *
     * @author David Carranza
     * @param obj
     * @param contadorTurnos
     */
    public void crearDetalle(CexHorariosDia obj, int contadorTurnos) {
        try {

            Integer porcentajeAgenda;
            BigDecimal numConsultas;
            BigDecimal num1;
            BigDecimal totTurnosAutAgenda;
            BigDecimal porAgendaRed;
            BigDecimal total;
            boolean act = false;
            int conArea = 1;

            Calendar horaSumada = new GregorianCalendar();
            int contPorcentaje = 1;
            porcentajeAgenda = obj.getCexHorario().getChoPorcentajeAgenda();

            //Calcular la Hora
            //Calcular los tiempos para cada turno
            horaInicioAm.setTime(obj.getChdHoraInicioAm());
            horaFinAm.setTime(obj.getChdHoraFinAm());
            long iniAm = horaInicioAm.getTimeInMillis();
            long finAm = horaFinAm.getTimeInMillis();
            //calcular total de minitos al dia asignado al medico
            long totHoras = (finAm - iniAm);

            // calcular la diferencia en milisengundos
            //long diff = milis2 - milis1;
            // calcular la diferencia en segundos
            //long diffSeconds = diff / 1000;
            // calcular la diferencia en minutos
            diffMinutes = totHoras / (60 * 1000);

            // calcular la diferencia en horas
            //long diffHours = diff / (60 * 60 * 1000);
            // calcular la diferencia en dias
            //long diffDays = diff / (24 * 60 * 60 * 1000);
            rangoMuinutos = divisionControlada(new BigDecimal(diffMinutes), divisionControlada(new BigDecimal(obj.getChdNumConsultas()), new BigDecimal(obj.getChdIntervalo())));
            rangoMuinutos = rangoMuinutos.setScale(0, RoundingMode.HALF_UP);

            //Recorrer los horarios dias para crear
            //Crear turnos de acuerdo al porcentaje de aggenda para el medico
            numConsultas = new BigDecimal(obj.getChdNumConsultas());
            num1 = (numConsultas.multiply(new BigDecimal(porcentajeAgenda)));
            totTurnosAutAgenda = divisionControlada(num1, new BigDecimal(100));
            porAgendaRed = totTurnosAutAgenda.setScale(0, RoundingMode.HALF_UP);
            total = numConsultas.subtract(porAgendaRed);

            for (int i = 1; i <= obj.getChdNumConsultas(); i++) {
                //Definir el tipo que es para identificar el porcentaje que maneja el medico para asignar turnos
                if (i <= total.intValue()) {
                    if (!act && numConsultas.intValue() > 1) {
                        if (total.intValue() > 2 && i == (total.intValue() - 1)) {
                            agenda.setCagTipo(3);
                            act = true;
                        } else {
                            if (total.intValue() < 3 && conArea == 2) {
                                agenda.setCagTipo(3);
                                act = true;
                            } else {
                                agenda.setCagTipo(0);
                            }
                            conArea++;
                        }
                    } else {
                        agenda.setCagTipo(0);
                    }
                } else {
                    agenda.setCagTipo(1);
                }
                agenda.setCagSecuencia(contadorTurnos);
                agenda.setCexHorariosDia(obj);
                agenda.setCagEstado(0);
                agenda.setCexHistoriaClinica(null);
                agenda.setCagFecha(fechaAgenda);
                if (obj.getChdIntervalo() == 1) {
                    if (i == 1) {
                        agenda.setCagHora(horaInicioAm.getTime());
                        horaSumada = horaInicioAm;
                    } else {
                        horaSumada.add(Calendar.MINUTE, rangoMuinutos.intValue());
                        agenda.setCagHora(horaSumada.getTime());
                    }
                } else {
                    if (contPorcentaje <= obj.getChdIntervalo()) {
                        if (i == 1) {
                            agenda.setCagHora(horaInicioAm.getTime());
                            horaSumada = horaInicioAm;
                        } else {
                            agenda.setCagHora(horaSumada.getTime());
                        }

                    } else {
                        horaSumada.add(Calendar.MINUTE, rangoMuinutos.intValue());
                        agenda.setCagHora(horaSumada.getTime());
                        contPorcentaje = 1;

                    }
                    contPorcentaje++;
                }

                adminObject.crear(agenda, (UsuarioAdmin) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user"));
                agenda = new CexAgenda();
                contadorTurnos = contadorTurnos + 1;
                // sacar la lista de detalle
                //turnosLibres = listaHorarioDia.size();
            }

            //int totTurnosAut = numConsultas.intValue() - porAgendaRed.intValue();
            // listaHorarioDia = adminObject.listarOrdenada(CexAgenda.class, "cexHorariosDia", object, "ageFecha", fechaAgenda, "ageTipo", 1, "ageSecuencia", false);
        } catch (Exception e) {
            log.error("{}: {} ", "crearDetalle", e);
        }
    }

    /**
     * Funcion que divide dos numero BigDecimales en el caso de que el resultado
     * sea mas extenso de lo que este puede abarcar en la expecion lo divide
     * como double
     *
     * @param A
     * @param B
     * @return BigDe
     */
    public static BigDecimal divisionControlada(BigDecimal A, BigDecimal B) {
        try {
            return A.divide(B);
        } catch (Exception e) {
            return new BigDecimal(A.doubleValue() / B.doubleValue());
        }
    }

    /**
     * Implementa el comportamiento para inicializar los datos del objeto a
     * administrar.
     *
     * @return null, retorna a la página invocada.
     */
    public String nuevoActionPaciente() {
        hcPaciente = new CexHistoriaClinica();
        return null;
    }

    /**
     * Implementa el comportamiento para inicializar los datos del objeto a
     * administrar.
     *
     * @return null, retorna a la página invocada.
     */
    public String limpiarMedico() {
        //detalle.setCexMedico(new CexMedico());
        //especialidad = new CexEspecialidad();
        //subEspecialidad = new CexEspecialidad();
        object = new CexEspecialidadMedico();
        listaHorarioMed = new ArrayList<>();
        listaAgenda = new ArrayList<>();
        return null;
    }

    public String cargarPaciente(CexHistoriaClinica obj) {
        //inicializar();
        try {
            hcHistoria = new CexHistoriaClinica();
            agenda.setCexHistoriaClinica(obj);
            Boolean valido1 = verificarDatosHc(agenda.getCexHistoriaClinica());
            hcHistoria = agenda.getCexHistoriaClinica();
            if (hcHistoria.getAdmDivisionPolitica() != null) {
                parroquia = hcHistoria.getAdmDivisionPolitica();
                canton = parroquia.getAdmDivisionPolitica();
                provincia = canton.getAdmDivisionPolitica();
            }
            if (hcHistoria.getChcEstado() == 1) {
                activo = true;
            } else {
                if (hcHistoria.getChcEstado() == 0 || hcHistoria.getChcEstado() == 2) {
                    activo = false;
                }
            }
            if (hcHistoria.getChcTipoIngreso() != 5) {
                if (valido1) {
                    agenda = new CexAgenda();
                    parroquia = new AdmDivisionPolitica();
                    canton = new AdmDivisionPolitica();
                    provincia = new AdmDivisionPolitica();
                }
            }

        } catch (Exception e) {
            log.error("{}: {} ", "cargarPaciente", e);
        }
        return null;
    }

    public String nuevaBusqueda() {
        //inicializar();
        listaHClinica = new ArrayList<>();
        return null;
    }

    /**
     * Obtiene una lista de objetos de tipo SelectedItem.
     *
     * @return la lista
     */
    @Override
    public List<SelectItem> getSelectedItem() {
//        try {
//            List<CexTurnosEnc> datos = admin.listarOrdenada(object.getClass(), "nombre", true);
//            List<SelectItem> items = new ArrayList<SelectItem>();
//            for (CexTurnosEnc obj : datos) {
//                items.add(new SelectItem(obj, obj.get));
//            }
//            return items;
//        } catch (Exception e) {
//            log.error("getSelectedItem() {} ", e.getMessage());
//        }
        return null;
    }

    /**
     * Obtiene una lista de objetos de tipo SelectedItem.
     *
     * @return la lista
     */
    public List<SelectItem> getSelectedItemEspe() {
        try {
            //listaHorarioDia = new ArrayList<CexTurnosDet>();
            //detalle.setCexMedico(null);

            List<CexEspecialidad> listEspecialidad = adminObject.listarNullOrdenada(CexEspecialidad.class, "cexEspecialidad", "cesEstado", 1, "cesNombre", true);
            List<SelectItem> items = new ArrayList<>();
            for (CexEspecialidad obj : listEspecialidad) {
                // if (user.getUser().getAdmEmpleado().getAdmDepartamento().getIdDepartamento() == 2 || user.getUser().getAdmEmpleado().getAdmDepartamento().getIdDepartamento() == 1) {
                items.add(new SelectItem(obj, obj.getCesNombre()));
                // } else if (user.getUser().getAdmEmpleado().getAdmDepartamento().getIdDepartamento() == 3) {
                //      if (obj.getCesId().equals(12)) {
                // items.add(new SelectItem(obj, obj.getCesNombre()));
                //    }
                // }

            }
            return items;
        } catch (Exception e) {
            log.error("getSelectedItemEspe() {} ", e.getMessage());
        }
        return null;
    }

    /**
     * Obtiene una lista de objetos de tipo SelectedItem.
     *
     * @return la lista
     */
    public List<SelectItem> getSelectedItemSubespecialidad() {
        try {
            //listaHorarioDia = new ArrayList<CexTurnosDet>();
            //detalle.setCexMedico(null);
            //List<CexEspecialidad> subespecialidad = adminObject.listarOrdenada(CexEspecialidad.class, "cexEspecialidad", especialidad, "cesEstado", 1, "cesNombre", true);
            List<SelectItem> items = new ArrayList<>();
            for (CexEspecialidad obj : especialidad.getCexEspecialidadList()) {
                if (obj.getCesEstado().equals(1)) {
                    items.add(new SelectItem(obj, obj.getCesNombre()));
                }
            }
            return items;
        } catch (Exception e) {
            log.error("getSelectedItemSubespecialidad() {} ", e.getMessage());
        }
        return null;
    }

    /**
     * Metodo generico que carga el horario del medico seleccionado
     *
     * @author David Carranza
     */
    public void cargarHorario() {
        listaHorarioMed.clear();
        CexHorario hor = new CexHorario();
        hor.setCexHorariosDiaList(new ArrayList<CexHorariosDia>());
        try {
            for (CexHorario cexHor : object.getCexHorarioList()) {
                if (cexHor.getAdmTipoConsulta().equals(admTipoConsulta)) {
                    for (CexHorariosDia cexHorariosDia1 : cexHor.getCexHorariosDiaList()) {
                        if (cexHorariosDia1.getChdHoraInicioAm() != null && cexHorariosDia1.getChdHoraFinAm() != null) {
                            hor.getCexHorariosDiaList().add(cexHorariosDia1);
                        }
                    }
                    listaHorarioMed.add(hor);
                    hor = new CexHorario();
                    hor.setCexHorariosDiaList(new ArrayList<CexHorariosDia>());
                }

            }

        } catch (Exception e) {
            log.error("{}: {} ", "cargarHorario", e);
        }

    }

    public List<SelectItem> getSelectedItemMedico() {
        try {
            c1 = Calendar.getInstance();
            c1.setTime(fechaAgenda);
            dia = c1.get(Calendar.DAY_OF_WEEK);
            List<CexEspecialidadMedico> listEspMed = new ArrayList<>();
            // lista los horarios pertenecientes al emdico de acuerdo a la especialidad
            //List<CexHorario> listaHorario1 = adminObject.listarOrdenada(CexHorario.class, "cexEspecialidadMedico.cexEspecialidad", subEspecialidad, "admTipoConsulta", admTipoConsulta, "choId", true);
            // Filtra los horarios segun el dia actual
            List<SelectItem> items = new ArrayList<>();
            for (CexEspecialidadMedico cexEspMed : subEspecialidad.getCexEspecialidadMedicoList()) {
                for (CexHorario cexHorario : cexEspMed.getCexHorarioList()) {
                    if (cexHorario.getAdmTipoConsulta().equals(admTipoConsulta)) {
                        for (CexHorariosDia cexHorarioDia1 : cexHorario.getCexHorariosDiaList()) {
                            //Validar que sea el dia actual
                            if (cexHorarioDia1.getCexDia().getCdiId().equals(dia)) {
                                if (cexHorarioDia1.getChdHoraInicioAm() != null || cexHorarioDia1.getChdHoraFinAm() != null) {
                                    if (cexHorarioDia1.getCexHorario().getCexEspecialidadMedico().getAdmMedico().getAmeEstado() == 1) {
                                        if (!listEspMed.contains(cexHorarioDia1.getCexHorario().getCexEspecialidadMedico())) {
                                            items.add(new SelectItem(cexHorarioDia1.getCexHorario().getCexEspecialidadMedico(), cexHorarioDia1.getCexHorario().getCexEspecialidadMedico().getAdmMedico().getAmeNombreFull()));
                                            listEspMed.add(cexHorarioDia1.getCexHorario().getCexEspecialidadMedico());
                                        }
                                    }
                                }
                            }
                        }
                    }

                }
            }
            return items;
        } catch (Exception e) {
            log.error("getSelectedItemMedico() {} ", e.getMessage());
        }
        return null;
    }

    /**
     * Metodo que cancela un turno de la lista de Agenda asignado anteriormente.
     *
     * @param listaAgd
     */
    public void cancelarTurnoAgenda(List<CexAgenda> listaAgd) {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "()";
        FacesContext context = FacesContext.getCurrentInstance();

        try {
            String valorDocumento;
            String codigoDocumento;
            Integer idDocumento;
            boolean isCancelar = false;
            //Verifica permisp

            for (Map.Entry e : user.getPermisosMap().entrySet()) {
                if (e.getKey().equals("cancelarCexAgenda")) {
                    isCancelar = true;
                    break;
                }
            }
            //Ingresa si posee permiso para Cancelar turno
            if (isCancelar) {
                //Recorrer la lista de Agenda
                for (CexAgenda objecto : listaAgd) {
                    //Preguntar por el seleccionado
                    if (objecto.isSeleccionado()) {
                        if (objecto.getCagTipo() == 0) {
                            if (!objecto.getCexPreparacionList().isEmpty() || objecto.getCexPreparacionList().size() > 0) {
                                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "No se puede cancelar turno, paciente ya tiene preparación ingresada", "No se puede cancelar turno, paciente ya tiene preparación ingresada"));
                            } else {
                                idDocumento = objecto.getCagId();
                                codigoDocumento = objecto.getCexHistoriaClinica().getChcHistoriaClinica();
                                valorDocumento = Integer.toString(objecto.getCagSecuencia());
                                objecto.setCexHistoriaClinica(null);
                                objecto.setCagEstado(0);
                                objecto.setSeleccionado(false);
                                objecto.setCagFechaRegistro(null);
                                objecto.setCagHoraRegistro(null);
                                objecto.setCagIdUsuario(user.getUser().getIdUsuario().intValue());
                                objecto.setCagNombreUsuario(user.getUser().getAdmEmpleado().getNombreFull());
                                hcAdmin.cancelarTurno(objecto, (UsuarioAdmin) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user"), idDocumento, codigoDocumento, valorDocumento);
                                agenda.setCexHistoriaClinica(new CexHistoriaClinica());
                                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_INFO, "Turno cancelado satisfactoriamente", "Turno cancelado"));

                            }
                        } else {
                            if (objecto.getCagTipo() == 2) {
                                if (!objecto.getCexPreparacionList().isEmpty() || objecto.getCexPreparacionList().size() > 0) {
                                    for (CexPreparacion cexPreparacionTemp : objecto.getCexPreparacionList()) {
                                        if (!cexPreparacionTemp.getCexConsultaList().isEmpty() || cexPreparacionTemp.getCexConsultaList().size() > 0) {
                                            FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "No se puede cancelar turno, paciente ya tiene consulta ingresada", "No se puede cancelar turno, paciente ya tiene consulta ingresada"));

                                        } else {
                                            FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "No se puede cancelar turno, paciente ya tiene preparación ingresada", "No se puede cancelar turno, paciente ya tiene preparación ingresada"));

                                        }

                                    }

                                } else {
                                    objecto.setSeleccionado(false);
                                    adminObject.eliminar(objecto, (UsuarioAdmin) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user"));
                                    objecto.setCexHistoriaClinica(null);
                                    objecto.setCagSecuencia(0);
                                    objecto.setCagEstado(0);
                                    objecto.setCagHora(null);

                                    agenda.setCexHistoriaClinica(new CexHistoriaClinica());
                                    FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_INFO, "Turno cancelado satisfactoriamente", "Turno cancelado"));
                                }

                            }
                            for (CexHorariosDia objHorDia : listaHorarioDia) {
                                objHorDia.getCexAgendaList().clear();
                                objHorDia.setCexAgendaList(adminObject.listarOrdenada(CexAgenda.class, "cexHorariosDia", objHorDia, "cagFecha", fechaAgenda, "cagSecuencia", true));
                            }
                            return;
                        }
                    }

                }
            } else {
                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Usuario no autorizado para cancelar turnos ", "Usuario no autorizado para cancelar turnos "));
            }

        } catch (Exception e) {
            log.error("{}: {} ", nombreMetodo, e);
        }
    }

    /**
     * Metodo que busca segun la especialidad , el Doctor y el horario que tiene
     * asignado cada doctor el turno mas cerca dispible
     *
     * @author David Carranza
     */
    public void buscarTurnoListener() {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "()";
        FacesContext context = FacesContext.getCurrentInstance();
        int contTurnos = 0;
        int cont1 = 1;
        int contHor = 0;
        boolean isContLibre = false;
        boolean isSelect = false;
        int nuevaSecuencia = 0;
        Calendar horaSumada = new GregorianCalendar();
        listaHorarioDia.clear();
        listaAgenda.clear();
        List<CexAgenda> listTempAgen;
        try {

            //Recupera permiso para saber si se puede agendar en la fecha seleccionada
            List<AdmPermiso> objLicencia = (List<AdmPermiso>) adminObject.queryEJB("select p from AdmPermiso p where :var1 between p.apeFechaInicio and p.apeFechaFin and p.admMedico = :var2", fechaAgenda, object.getAdmMedico());
            //List<CexPermiso> objLicencia = adminObject.ejecutarQueryNativoLista("SELECT * FROM cex_Permiso where med_id = " + object.getCexHorario().getCexEspecialidadMedico().getCexMedico().getMedId() + " and date('" + fecha + "') between per_fecha_inicio and per_fecha_fin;", CexPermiso.class);
            //Verifica si tiene permiso
            if (objLicencia.size() < 0 || objLicencia.isEmpty()) {
                //Recuper la lista del horario de acuerdo al dia seleciconado
                for (CexHorario objTemH : object.getCexHorarioList()) {
                    //Agregar horario de acuerdo a la fecha
                    if ((fechaAgenda.after(objTemH.getChoFechaInicio()) || objTemH.getChoFechaInicio().equals(fechaAgenda))
                            && (fechaAgenda.before(objTemH.getChoFechaFin()) || objTemH.getChoFechaFin().equals(fechaAgenda))) {
                        //Verificar los horarios segun el tipo de consulta de la agenda
                        if (objTemH.getAdmTipoConsulta().equals(admTipoConsulta)) {
                            //Recorrer los horarios dias de cada horario
                            for (CexHorariosDia objTemHd : objTemH.getCexHorariosDiaList()) {
                                if (objTemHd.getCexDia().getCdiId().equals(dia)) {
                                    //Añadir solo el horario que tenga asignado hora inicio y hora fin
                                    if (objTemHd.getChdHoraInicioAm() != null && objTemHd.getChdHoraFinAm() != null) {
                                        listaHorarioDia.add(objTemHd);
                                    }
                                }
                            }
                        }
                    }
                }

                //Recuperar las agendas de acuerdo al horarioDia y de acuerdo a las fechas
                for (CexHorariosDia objHorDia : listaHorarioDia) {
                    //Asignar numero de horario
                    objHorDia.setOrdenHorario(contHor);
                    listTempAgen = adminObject.listarOrdenada(CexAgenda.class, "cagFecha", fechaAgenda, "cexHorariosDia", objHorDia, "cagSecuencia", true);
                    for (CexAgenda objA : listTempAgen) {
                        objA.setNumeroHorario(contHor);
                        listaAgenda.add(objA);
                    }
                    listTempAgen.clear();
                    contHor++;
                }

                if (listaAgenda.isEmpty() || listaAgenda.size() <= 0) {
                    for (CexHorariosDia objHorD : listaHorarioDia) {
                        if (objHorD.getOrdenHorario() > 0) {
                            cont1 = cont1 + listaHorarioDia.get(objHorD.getOrdenHorario() - 1).getChdNumConsultas();
                        }
                        crearDetalle(objHorD, cont1);
                    }
                    isSelect = true;
                    isContLibre = true;
                } else {
                    // Comprobar si el numero de turnos es mayor o igual al numero asignado en los horarios del medico
                    // esto mas en el caso de los turnos migrados
                    for (CexHorariosDia objHorDi : listaHorarioDia) {
                        nuevaSecuencia = 0;
                        contTurnos = 0;
                        isContLibre = false;
                        for (CexAgenda cexAgetemp1 : listaAgenda) {

                            //Recorrer segun el numero de horarioDia
                            if (objHorDi.getOrdenHorario() == cexAgetemp1.getNumeroHorario()) {
                                if (cexAgetemp1.getCagTipo() == 0 || cexAgetemp1.getCagTipo() == 1 || cexAgetemp1.getCagTipo() == 3) {
                                    nuevaSecuencia++;
                                    contTurnos++;
                                }

                                if (cexAgetemp1.getCagEstado() == 0 && cexAgetemp1.getCagTipo() == 0) {
                                    isContLibre = true;
                                }
                            }

                        }

                        //Verificar Numero de turnos para agregar o quitar turnos
                        if (objHorDi.getChdNumConsultas() > contTurnos) {
                            //Se crea los turnos restantes 
                            int turnosRest = objHorDi.getChdNumConsultas() - contTurnos;
                            //Calcular la Hora
                            //Calcular los tiempos para cada turno
                            horaInicioAm.setTime(objHorDi.getChdHoraInicioAm());
                            horaFinAm.setTime(objHorDi.getChdHoraFinAm());
                            long iniAm = horaInicioAm.getTimeInMillis();
                            long finAm = horaFinAm.getTimeInMillis();
                            //calcular total de minitos al dia asignado al medico
                            long totHoras = (finAm - iniAm);

                            // calcular la diferencia en milisengundos
                            //long diff = milis2 - milis1;
                            // calcular la diferencia en segundos
                            //long diffSeconds = diff / 1000;
                            // calcular la diferencia en minutos
                            diffMinutes = totHoras / (60 * 1000);

                            // calcular la diferencia en horas
                            //long diffHours = diff / (60 * 60 * 1000);
                            // calcular la diferencia en dias
                            //long diffDays = diff / (24 * 60 * 60 * 1000);
                            rangoMuinutos = divisionControlada(new BigDecimal(diffMinutes), new BigDecimal(objHorDi.getChdNumConsultas()));
                            rangoMuinutos = rangoMuinutos.setScale(0, RoundingMode.HALF_UP);
                            //Asignar hora ultima
                            horaSumada.setTime(objHorDi.getCexAgendaList().get(objHorDi.getCexAgendaList().size() - 1).getCagHora());

                            for (int i = 1; i <= turnosRest; i++) {
                                agenda.setCagTipo(0);
                                agenda.setCagSecuencia(nuevaSecuencia + 1);
                                agenda.setCexHorariosDia(objHorDi);
                                agenda.setCagEstado(0);
                                agenda.setCexHistoriaClinica(null);
                                agenda.setCagFecha(fechaAgenda);
                                horaSumada.add(Calendar.MINUTE, rangoMuinutos.intValue());
                                agenda.setCagHora(horaSumada.getTime());
                                adminObject.crear(agenda, (UsuarioAdmin) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user"));
                                agenda = new CexAgenda();
                                isSelect = true;
                                nuevaSecuencia++;
                                //sacar la lista de detalle
                            }
                        } else {
                            //caso contrario elimina los turnos que estan demas en el nuevo horario
                            if (objHorDi.getChdNumConsultas() < contTurnos) {
                                // Se crea los turnos restantes que no esten asignados turnos
                                //los que esten quedan visibles para reasignar
                                int cont = 0;
                                int turnosEliminar = contTurnos - objHorDi.getChdNumConsultas();
                                for (CexAgenda cexAgendaTemp : listaAgenda) {
                                    if (cexAgendaTemp.getNumeroHorario() == objHorDi.getOrdenHorario()) {
                                        if (cont != turnosEliminar) {
                                            if (cexAgendaTemp.getCexHistoriaClinica() == null) {
                                                adminObject.eliminar(cexAgendaTemp, (UsuarioAdmin) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user"));
                                                cont++;
                                                isSelect = true;
                                            }
                                        }
                                    }

                                }
                            }
                        }
                    }

                }

                if (isSelect) {
                    contHor = 0;
                    //Limpia la lista originay y carga los nuevos valores 
                    //Recuperar las agendas de acuerdo al horarioDia y de acuerdo a las fechas
                    listaAgenda.clear();
                    for (CexHorariosDia objHorDia : listaHorarioDia) {
                        //Asignar numero de horario
                        objHorDia.setOrdenHorario(contHor);
                        listTempAgen = adminObject.listarOrdenada(CexAgenda.class, "cagFecha", fechaAgenda, "cexHorariosDia", objHorDia, "cagSecuencia", true);
                        for (CexAgenda objA : listTempAgen) {
                            objA.setNumeroHorario(contHor);
                            listaAgenda.add(objA);
                        }
                        listTempAgen.clear();
                        contHor++;
                    }
                }

                cargarHorario();
            } else {
                AdmPermiso permiso = objLicencia.get(0);
                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Agenda no disponible", "Médico no disponible en la fecha ha seleccioanda por motico de " + permiso.getApeMotivo() + ""));
            }

            if (!isContLibre) {
                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Agenda no disponible", "No dispone turnos libres para esta agenda"));
            }
        } catch (Exception e) {
            log.error("{}: {} ", nombreMetodo, e);
        }
    }

    /**
     * Metodo generico que crea un agenda de la agenda selecionada
     *
     * @param fechaSumada
     * @param obj
     * @author David Carranza
     * @param contadorTurnos
     * @return
     */
    public List<CexAgenda> crearDetalle(Date fechaSumada, CexHorariosDia obj, int contadorTurnos) {
        List<CexAgenda> lisTem = new ArrayList<>();
        try {

            Integer porcentajeAgenda;
            BigDecimal numConsultas;
            BigDecimal num1;
            BigDecimal totTurnosAutAgenda;
            BigDecimal porAgendaRed;
            BigDecimal total;
            boolean act = false;
            int conArea = 1;

            Calendar horaSumada = new GregorianCalendar();
            int contPorcentaje = 1;
            porcentajeAgenda = obj.getCexHorario().getChoPorcentajeAgenda();

            //Calcular la Hora
            //Calcular los tiempos para cada turno
            horaInicioAm.setTime(obj.getChdHoraInicioAm());
            horaFinAm.setTime(obj.getChdHoraFinAm());
            long iniAm = horaInicioAm.getTimeInMillis();
            long finAm = horaFinAm.getTimeInMillis();
            //calcular total de minitos al dia asignado al medico
            long totHoras = (finAm - iniAm);

            // calcular la diferencia en milisengundos
            //long diff = milis2 - milis1;
            // calcular la diferencia en segundos
            //long diffSeconds = diff / 1000;
            // calcular la diferencia en minutos
            diffMinutes = totHoras / (60 * 1000);

            // calcular la diferencia en horas
            //long diffHours = diff / (60 * 60 * 1000);
            // calcular la diferencia en dias
            //long diffDays = diff / (24 * 60 * 60 * 1000);
            rangoMuinutos = divisionControlada(new BigDecimal(diffMinutes), divisionControlada(new BigDecimal(obj.getChdNumConsultas()), new BigDecimal(obj.getChdIntervalo())));
            rangoMuinutos = rangoMuinutos.setScale(0, RoundingMode.HALF_UP);

            //Recorrer los horarios dias para crear
            //Crear turnos de acuerdo al porcentaje de aggenda para el medico
            numConsultas = new BigDecimal(obj.getChdNumConsultas());
            num1 = (numConsultas.multiply(new BigDecimal(porcentajeAgenda)));
            totTurnosAutAgenda = divisionControlada(num1, new BigDecimal(100));
            porAgendaRed = totTurnosAutAgenda.setScale(0, RoundingMode.HALF_UP);
            total = numConsultas.subtract(porAgendaRed);

            for (int i = 1; i <= obj.getChdNumConsultas(); i++) {
                //Definir el tipo que es para identificar el porcentaje que maneja el medico para asignar turnos
                if (i <= total.intValue()) {
                    if (!act && numConsultas.intValue() > 1) {
                        if (total.intValue() > 2 && i == (total.intValue() - 1)) {
                            agenda.setCagTipo(3);
                            act = true;
                        } else {
                            if (total.intValue() < 3 && conArea == 2) {
                                agenda.setCagTipo(3);
                                act = true;
                            } else {
                                agenda.setCagTipo(0);
                            }
                            conArea++;
                        }
                    } else {
                        agenda.setCagTipo(0);
                    }
                } else {
                    agenda.setCagTipo(1);
                }
                agenda.setCagSecuencia(contadorTurnos);
                agenda.setCexHorariosDia(obj);
                agenda.setCagEstado(0);
                agenda.setCexHistoriaClinica(null);
                agenda.setCagFecha(fechaSumada);
                if (obj.getChdIntervalo() == 1) {
                    if (i == 1) {
                        agenda.setCagHora(horaInicioAm.getTime());
                        horaSumada = horaInicioAm;
                    } else {
                        horaSumada.add(Calendar.MINUTE, rangoMuinutos.intValue());
                        agenda.setCagHora(horaSumada.getTime());
                    }
                } else {
                    if (contPorcentaje <= obj.getChdIntervalo()) {
                        if (i == 1) {
                            agenda.setCagHora(horaInicioAm.getTime());
                            horaSumada = horaInicioAm;
                        } else {
                            agenda.setCagHora(horaSumada.getTime());
                        }

                    } else {
                        horaSumada.add(Calendar.MINUTE, rangoMuinutos.intValue());
                        agenda.setCagHora(horaSumada.getTime());
                        contPorcentaje = 1;

                    }
                    contPorcentaje++;
                }

                adminObject.crear(agenda, (UsuarioAdmin) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user"));
                agenda = new CexAgenda();
                contadorTurnos = contadorTurnos + 1;
                // sacar la lista de detalle
                //turnosLibres = listaHorarioDia.size();
            }

            //int totTurnosAut = numConsultas.intValue() - porAgendaRed.intValue();
            // listaHorarioDia = adminObject.listarOrdenada(CexAgenda.class, "cexHorariosDia", object, "ageFecha", fechaAgenda, "ageTipo", 1, "ageSecuencia", false);
        } catch (Exception e) {
            log.error("{}: {} ", "crearDetalle", e);
        }
        return lisTem;
    }

    public void onRowEdit(RowEditEvent event) {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "()";
        try {
            CexAgenda objAgen = (CexAgenda) event.getObject();
            adminObject.modificar(objAgen, (UsuarioAdmin) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user"));
        } catch (Exception e) {
            log.error("{}: {} ", nombreMetodo, e);
        }
    }

    public void onRowCancel(RowEditEvent event) {
        FacesMessage msg = new FacesMessage("Edit Cancelled", ((CexAgenda) event.getObject()).getCagObservacion());
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }

    /**
     * Metodo verifica si existen turnos disponibles para la ventanilla cuando
     * sea de tipo 1
     *
     * @author David Carranza
     */
    public void bloquearTurno() {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "()";
        FacesContext context = FacesContext.getCurrentInstance();
        try {
            boolean isGraba = false;
            for (CexAgenda cexAge : listaAgenda) {
                if (cexAge.getCagEstado() == 0 && cexAge.isSeleccionado()) {
                    cexAge.setCagEstado(4);
                    cexAge.setCagObservacion(motivoBloqueo.toUpperCase());
                    adminObject.modificar(cexAge, (UsuarioAdmin) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user"));
                    isGraba = true;
                }
            }
            if (isGraba) {
                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_INFO, "Agenda Bloqueada", "Se bloqueo correctamente la agenda cierrre la ventana emergente"));
            }
        } catch (Exception e) {
            log.error("{}: {} ", nombreMetodo, e);
        }
    }

    /**
     * Metodo que agregar una observacion a la cancelaciond e turno
     *
     * @author David Carranza
     */
    public void cancelarTurno() {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "()";
        FacesContext context = FacesContext.getCurrentInstance();
        try {
            String valorDocumento;
            String codigoDocumento;
            Integer idDocumento;
            boolean isCancelar = false;
            //Verifica permisp

            for (Map.Entry e : user.getPermisosMap().entrySet()) {
                if (e.getKey().equals("cancelarCexAgenda")) {
                    isCancelar = true;
                    break;
                }
            }
            //Ingresa si posee permiso para Cancelar turno
            if (isCancelar) {
                //Recorrer la lista de turnos a eliminar
                for (CexAgenda objecto : listaAgenda) {
                    //Preguntar por el seleccionado
                    if (objecto.isSeleccionado()) {
                        if (objecto.getCagTipo() == 0) {
                            if (!objecto.getCexPreparacionList().isEmpty() || objecto.getCexPreparacionList().size() > 0) {
                                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "No se puede cancelar turno, paciente ya tiene preparación ingresada", "No se puede cancelar turno, paciente ya tiene preparación ingresada"));
                            } else {
                                idDocumento = objecto.getCagId();
                                codigoDocumento = objecto.getCexHistoriaClinica().getChcHistoriaClinica();
                                valorDocumento = Integer.toString(objecto.getCagSecuencia());
                                objecto.setCexHistoriaClinica(null);
                                objecto.setCagObservacion(motivoCancelar);
                                objecto.setCagEstado(0);
                                objecto.setSeleccionado(false);
                                hcAdmin.cancelarTurno(objecto, (UsuarioAdmin) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user"), idDocumento, codigoDocumento, valorDocumento);
                                agenda.setCexHistoriaClinica(new CexHistoriaClinica());
                                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_INFO, "Turno cancelado satisfactoriamente", "Turno cancelado"));

                            }
                        } else {
                            if (objecto.getCagTipo() == 2) {
                                if (!objecto.getCexPreparacionList().isEmpty() || objecto.getCexPreparacionList().size() > 0) {
                                    for (CexPreparacion cexPreparacionTemp : objecto.getCexPreparacionList()) {
                                        if (!cexPreparacionTemp.getCexConsultaList().isEmpty() || cexPreparacionTemp.getCexConsultaList().size() > 0) {
                                            FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "No se puede cancelar turno, paciente ya tiene consulta ingresada", "No se puede cancelar turno, paciente ya tiene consulta ingresada"));

                                        } else {
                                            FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "No se puede cancelar turno, paciente ya tiene preparación ingresada", "No se puede cancelar turno, paciente ya tiene preparación ingresada"));

                                        }

                                    }

                                } else {
                                    objecto.setSeleccionado(false);
                                    adminObject.eliminar(objecto, (UsuarioAdmin) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user"));
                                    objecto.setCexHistoriaClinica(null);
                                    objecto.setCagSecuencia(0);
                                    objecto.setCagEstado(0);
                                    objecto.setCagHora(null);

                                    agenda.setCexHistoriaClinica(new CexHistoriaClinica());
                                    FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_INFO, "Turno cancelado satisfactoriamente", "Turno cancelado"));
                                }

                            }
                            for (CexHorariosDia objHorDia : listaHorarioDia) {
                                objHorDia.getCexAgendaList().clear();
                                objHorDia.setCexAgendaList(adminObject.listarOrdenada(CexAgenda.class, "cexHorariosDia", objHorDia, "cagFecha", fechaAgenda, "cagSecuencia", true));
                            }
                        }
                    }
                }
                object = new CexEspecialidadMedico();
            } else {
                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Usuario no autorizado para cancelar turnos ", "Usuario no autorizado para cancelar turnos "));
            }
        } catch (Exception e) {
            log.error("{}: {} ", nombreMetodo, e);
        }
    }

    /**
     * Metodo que hace un barrido del registro encontrando valores que deben
     * llenarse
     *
     *
     * @author David Carranza
     * @param obj
     * @return
     */
    public Boolean verificarDatosHc(CexHistoriaClinica obj) {
        FacesContext context = FacesContext.getCurrentInstance();
        if (obj.getChcApellidoPaterno() != null) {
            if (obj.getChcApellidoPaterno().isEmpty() || "".equals(obj.getChcApellidoPaterno())) {
                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "valorBusqueda").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Datos incompletos", "No se encuentra agregado apellido paterno"));
                return true;
            }
        } else {
            FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "valorBusqueda").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Datos incompletos", "No se encuentra agregado apellido paterno"));
            return true;
        }

        if (obj.getChcPrimerNombre() != null) {
            if (obj.getChcPrimerNombre().isEmpty() || "".equals(obj.getChcPrimerNombre())) {
                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "valorBusqueda").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Datos incompletos", "No se encuentra agregado primer nombre"));
                return true;
            }
        } else {
            FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "valorBusqueda").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Datos incompletos", "No se encuentra agregado primer nombre"));
            return true;
        }

        if (obj.getChcHistoriaClinica() != null) {
            if (obj.getChcHistoriaClinica().isEmpty() || "".equals(obj.getChcHistoriaClinica())) {
                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "valorBusqueda").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Datos incompletos", "No se encuentra agregado numero de historia clínica"));
                return true;
            }
        } else {
            FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "valorBusqueda").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Datos incompletos", "No se encuentra agregado numero de historia clínica"));
            return true;
        }

        if (obj.getChcDireccion() != null) {
            if (obj.getChcDireccion().isEmpty() || "".equals(obj.getChcDireccion())) {
                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "valorBusqueda").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Datos incompletos", "No se encuentra agregada dirección domiciliaria"));
                return true;
            }
        } else {
            FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "valorBusqueda").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Datos incompletos", "No se encuentra agregada dirección domiciliaria"));
            return true;
        }

        if (obj.getChcBarrio() != null) {
            if (obj.getChcBarrio().isEmpty() || "".equals(obj.getChcBarrio())) {
                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "valorBusqueda").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Datos incompletos", "No se encuentra agregado barrio"));
                return true;
            }
        } else {
            FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "valorBusqueda").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Datos incompletos", "No se encuentra agregado barrio"));
            return true;
        }

        if (obj.getAdmDivisionPolitica() == null) {
            FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "valorBusqueda").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Datos incompletos", "No se encuentra division politica"));
            return true;
        }

        if (obj.getChcFechaNacimiento() != null) {
            if (obj.getChcFechaNacimiento() == null || obj.getChcFechaNacimiento().equals("")) {
                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "valorBusqueda").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Datos incompletos", "No se encuentra agregada la fecha de nacimiento"));
                return true;
            }
        } else {
            FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "valorBusqueda").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Datos incompletos", "No se encuentra agregada la fecha de nacimiento"));
            return true;
        }

        if (obj.getChcLugarNacimiento() != null) {
            if (obj.getChcLugarNacimiento().isEmpty() || obj.getChcLugarNacimiento().equals("")) {
                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "valorBusqueda").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Datos incompletos", "No se encuentra agregado lugar de nacimiento"));
                return true;
            }
        } else {
            FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "valorBusqueda").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Datos incompletos", "No se encuentra agregado lugar de nacimiento"));
            return true;
        }

        if (obj.getCexNacionalidad() == null) {
            FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "valorBusqueda").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "No se encuentra agregado la nacionalidad del paciente", "No se encuentra agregado la nacionalidad del paciente"));
            return true;
        }

        if (obj.getCexGrupoCultural() == null) {
            FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "valorBusqueda").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "No se encuentra agregado el grupo cultural", "No se encuentra agregado el grupo cultural"));
            return true;
        }

        if (obj.getCexTipoSeguro() == null) {
            FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "valorBusqueda").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "No se encuentra agregado el tipo de seguro", "No se encuentra agregado el tipo de seguro"));
            return true;
        }
        return false;
    }

    /**
     * Metodo que busca una historia clinica
     *
     *
     * @author David Carranza
     */
    public void buscarHc() {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "()";
        FacesContext context = FacesContext.getCurrentInstance();
        try {
            hcHistoria = new CexHistoriaClinica();
            parametroBusqueda = parametroBusqueda.trim();
            if (parametroBusqueda.equals("")) {
                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "valorBusqueda").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Valor nullo no permitido", "Ingrese parametro de busqueda"));

            } else {
                if (tipoBusqueda == 1) {
                    if (admin.existePorCampo(CexHistoriaClinica.class, "chcHistoriaClinica", parametroBusqueda, "chcEstado", 1)) {
                        agenda.setCexHistoriaClinica((CexHistoriaClinica) adminObject.buscar(CexHistoriaClinica.class, "chcHistoriaClinica", parametroBusqueda, "chcEstado", 1));
                        Boolean valido1 = verificarDatosHc(agenda.getCexHistoriaClinica());
                        hcHistoria = agenda.getCexHistoriaClinica();

                        if (hcHistoria.getAdmDivisionPolitica() != null) {
                            parroquia = hcHistoria.getAdmDivisionPolitica();
                            canton = parroquia.getAdmDivisionPolitica();
                            provincia = canton.getAdmDivisionPolitica();
                        }

                        if (hcHistoria.getChcEstado() == 1) {
                            activo = true;
                        } else {
                            if (hcHistoria.getChcEstado() == 0 || hcHistoria.getChcEstado() == 2) {
                                activo = false;
                            }
                        }
                        if (hcHistoria.getChcTipoIngreso() != 5) {
                            if (valido1) {
                                agenda = new CexAgenda();
                            }
                        }

                        parametroBusqueda = "";
                    } else {
                        agenda.setCexHistoriaClinica(new CexHistoriaClinica());
                        FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "valorBusqueda").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Busqueda sin resultados", "No se encontro paciente"));
                    }
                }

                if (tipoBusqueda == 2) {
                    if (admin.existePorCampo(CexHistoriaClinica.class, "chcCedula", parametroBusqueda, "chcEstado", 1)) {
                        agenda.setCexHistoriaClinica(
                                (CexHistoriaClinica) adminObject.buscar(CexHistoriaClinica.class, "chcCedula", parametroBusqueda, "chcEstado", 1));
                        Boolean valido1 = verificarDatosHc(agenda.getCexHistoriaClinica());
                        hcHistoria = agenda.getCexHistoriaClinica();

                        if (hcHistoria.getAdmDivisionPolitica()
                                != null) {
                            parroquia = hcHistoria.getAdmDivisionPolitica();
                            canton = parroquia.getAdmDivisionPolitica();
                            provincia = canton.getAdmDivisionPolitica();
                        }

                        if (hcHistoria.getChcEstado()
                                == 1) {
                            activo = true;
                        } else {
                            if (hcHistoria.getChcEstado() == 0 || hcHistoria.getChcEstado() == 2) {
                                activo = false;
                            }
                        }
                        if (hcHistoria.getChcTipoIngreso() != 5) {
                            if (valido1) {
                                agenda = new CexAgenda();
                            }
                        }
                        parametroBusqueda = new String();
                    } else {
                        agenda.setCexHistoriaClinica(new CexHistoriaClinica());
                        FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "valorBusqueda").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Busqueda sin resultados", "No se encontro paciente"));
                    }
                } else if (tipoBusqueda == 3) {
                    if (admin.existePorCampo(CexHistoriaClinica.class, "chcPasaporte", parametroBusqueda, "chcEstado", 1)) {
                        agenda.setCexHistoriaClinica(
                                (CexHistoriaClinica) adminObject.buscar(CexHistoriaClinica.class, "chcPasaporte", parametroBusqueda, "chcEstado", 1));
                        Boolean valido1 = verificarDatosHc(agenda.getCexHistoriaClinica());
                        hcHistoria = agenda.getCexHistoriaClinica();

                        if (hcHistoria.getAdmDivisionPolitica()
                                != null) {
                            parroquia = hcHistoria.getAdmDivisionPolitica();
                            canton = parroquia.getAdmDivisionPolitica();
                            provincia = canton.getAdmDivisionPolitica();
                        }

                        if (hcHistoria.getChcEstado()
                                == 1) {
                            activo = true;
                        } else {
                            if (hcHistoria.getChcEstado() == 0 || hcHistoria.getChcEstado() == 2) {
                                activo = false;
                            }
                        }
                        if (hcHistoria.getChcTipoIngreso() != 5) {
                            if (valido1) {
                                agenda = new CexAgenda();
                            }
                        }
                        parametroBusqueda = new String();
                    } else {
                        agenda.setCexHistoriaClinica(new CexHistoriaClinica());
                        FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "valorBusqueda").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Busqueda sin resultados", "No se encontro paciente"));
                    }
                }
            }

        } catch (Exception e) {
            log.error("{}: {} ", nombreMetodo, e);
        }
    }

    /**
     * Metodo que busca una historia clinica por apellidos
     *
     *
     *
     *
     * @author David Carranza
     */
    public void buscarApellidos() {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "()";
        FacesContext context = FacesContext.getCurrentInstance();
        if (admin == null) {
            listaHClinica = null;
            return;
        }
        try {
            listaHClinica.clear();
            apellidoPbusqueda = apellidoPbusqueda.toUpperCase().trim();
            apellidoMbusqueda = apellidoMbusqueda.toUpperCase().trim();
            pnombrebusqueda = pnombrebusqueda.toUpperCase().trim();
            snombrePbusqueda = snombrePbusqueda.toUpperCase().trim();
            listaHClinica = (List<CexHistoriaClinica>) admin.queryEJB("select a from CexHistoriaClinica a where a.chcApellidoPaterno like :var1 and a.chcApellidoMaterno like :var2 and a.chcPrimerNombre like :var3 and a.chcSegundoNombre like :var4 and a.chcEstado = 1", "%" + apellidoPbusqueda + "%", "%" + apellidoMbusqueda + "%", "%" + pnombrebusqueda + "%", "%" + snombrePbusqueda + "%");
            //listaHClinica = admin.ejecutarQueryNativoLista("SELECT * from cex_historia_clinica WHERE hc_apellido_paterno LIKE '%" + apellidoPbusqueda + "%' and hc_apellido_materno like '%" + apellidoMbusqueda + "%' and hc_primer_nombre like '%" + pnombrebusqueda + "%' and hc_segundo_nombre like '%" + snombrePbusqueda + "%' and hc_estado = 1 ; ", CexHistoriaClinica.class);
            if (listaHClinica.isEmpty() || listaHClinica.size() <= 0) {
                listaHClinica.clear();
            }
        } catch (Exception e) {
            log.error("{}: {} ", nombreMetodo, e);
        }

    }

    /*
     * Metodo que imprime directamente en una impresra byte
     */
    public void print(CexAgenda turno) throws IOException {
        //FileInputStream inputStream = null;
        InputStream tex = null;
        SimpleDateFormat sf = new SimpleDateFormat("dd/MM/yyyy");
        String fecha = sf.format(turno.getCagFecha());
        SimpleDateFormat sfHora = new SimpleDateFormat("HH:mm");
        String hora = "";
        if (turno.getCagHora() != null) {
            hora = sfHora.format(turno.getCagHora());
        }
        String impresora = "SIN IMPRESORA";
        PrintService impresora11 = null;

        try {
            //inputStream = new FileInputStream("e:/archivo.txt");

            String cadena = "************************************* \n\n"
                    + "RESPONSABLE: " + turno.getCagNombreUsuario() + " \n"
                    + "FECHA: " + fecha + " \n"
                    + turno.getCagNombreInstitucion() + "\n"
                    + turno.getCexHorariosDia().getCexHorario().getCexEspecialidadMedico().getCexEspecialidad().getCesNombre() + "\n"
                    + "NÚMERO CARPETA: " + turno.getCexHistoriaClinica().getChcHistoriaClinica() + "\n"
                    + "CÉDULA: " + turno.getCexHistoriaClinica().getChcCedula() + "\n"
                    + "TURNO: " + turno.getCagSecuencia() + "\t HORA: " + hora + " \n"
                    + "MEDICO: " + turno.getCexHorariosDia().getCexHorario().getCexEspecialidadMedico().getAdmMedico().getAmeNombreFull() + "\n"
                    + "PACIENTE: " + turno.getCexHistoriaClinica().getChcNombreFull() + "\n"
                    + "***************************************\n"
                    + "\n"
                    + "\n"
                    + "SE RECOMIENDA ESTAR 30 MIN ANTES\n"
                    + " DE LA HORA ESPECIFICADA\n"
                    + "\n";
            String te2 = converteCaracter(cadena);
            tex = new ByteArrayInputStream(te2.getBytes("UTF-8"));

        } catch (UnsupportedEncodingException e) {
            log.error("printExtra() {} ", e.getMessage());
        }
        if (tex == null) {
            return;
        }

        DocFlavor docFormat = DocFlavor.INPUT_STREAM.AUTOSENSE;
        Doc document = new SimpleDoc(tex, docFormat, null);

        PrintRequestAttributeSet attributeSet = new HashPrintRequestAttributeSet();

        for (AdmDatosGlobales datoGlobal : listaImpresorasturnos) {
            if (user.getIp().equals(datoGlobal.getClave())) {
                impresora = datoGlobal.getValor();
                break;
            }
        }
        ////       impresora11 = PrintServiceLookup.lookupDefaultPrintService();
        PrintService[] printService = PrintServiceLookup.lookupPrintServices(null, null);
        for (PrintService printService1 : printService) {
            if (printService1.getName().equals(impresora)) {
                impresora11 = printService1;
            }
        }

        if (impresora11 != null) {
            DocPrintJob printJob = impresora11.createPrintJob();
            try {

                printJob.print(document, attributeSet);
            } catch (PrintException e) {
                log.error("printExtra() {} ", e.getMessage());
            }
        } else {
            log.error("No existen impresoras instaladas");
            for (PrintService printService1 : printService) {
                log.error(printService1.getName());
            }

        }

        tex.close();
    }

    /*
     * Metodo que imprime una lista de turnos directamente en una impresra byte
     */
    public void printLista(List<CexHorariosDia> listaTurno) throws IOException {
        //FileInputStream inputStream = null;
        InputStream tex = null;
        SimpleDateFormat sf = new SimpleDateFormat("dd/MM/yyyy");
        String fecha;
        SimpleDateFormat sfHora = new SimpleDateFormat("HH:mm");
        String hora = "";
        String te2;
        DocFlavor docFormat;
        Doc document;
        DocPrintJob printJob;
        PrintService impresora11 = null;
        String impresora = "SIN IMPRESORA";
        for (CexHorariosDia horD : listaTurno) {
            for (CexAgenda turno : horD.getCexAgendaList()) {
                if (turno.isSeleccionado()) {

                    fecha = sf.format(turno.getCagFecha());
                    try {

                        if (turno.getCagHora() != null) {
                            hora = sfHora.format(turno.getCagHora());
                        }

                        //inputStream = new FileInputStream("e:/archivo.txt");
                        String cadena = "************************************* \n\n"
                                + "RESPONSABLE: " + turno.getCagNombreUsuario() + " \n"
                                + "FECHA: " + fecha + " \n"
                                + turno.getCagNombreInstitucion() + "\n"
                                + turno.getCexHorariosDia().getCexHorario().getCexEspecialidadMedico().getCexEspecialidad().getCesNombre() + "\n"
                                + "NÚMERO CARPETA: " + turno.getCexHistoriaClinica().getChcHistoriaClinica() + "\n"
                                + "CÉDULA: " + turno.getCexHistoriaClinica().getChcCedula() + "\n"
                                + "TURNO: " + turno.getCagSecuencia() + "\t HORA: " + hora + " \n"
                                + "MEDICO: " + turno.getCexHorariosDia().getCexHorario().getCexEspecialidadMedico().getAdmMedico().getAmeNombreFull() + "\n"
                                + "PACIENTE: " + turno.getCexHistoriaClinica().getChcNombreFull() + "\n"
                                + "***************************************\n"
                                + "\n"
                                + "\n"
                                + "SE RECOMIENDA ESTAR 30 MIN ANTES\n"
                                + " DE LA HORA ESPECIFICADA\n"
                                + "\n";
                        te2 = converteCaracter(cadena);
                        tex = new ByteArrayInputStream(te2.getBytes("UTF-8"));

                    } catch (UnsupportedEncodingException e) {
                        log.error("printExtra() {} ", e.getMessage());
                    }
                    if (tex == null) {
                        return;
                    }

                    docFormat = DocFlavor.INPUT_STREAM.AUTOSENSE;
                    document = new SimpleDoc(tex, docFormat, null);

                    PrintRequestAttributeSet attributeSet = new HashPrintRequestAttributeSet();

                    for (AdmDatosGlobales datoGlobal : listaImpresorasturnos) {
                        if (user.getIp().equals(datoGlobal.getClave())) {
                            impresora = datoGlobal.getValor();
                            break;
                        }
                    }
                    //   impresora11 = PrintServiceLookup.lookupDefaultPrintService();
                    PrintService[] printService = PrintServiceLookup.lookupPrintServices(null, null);
                    for (PrintService printService1 : printService) {
                        if (printService1.getName().equals(impresora)) {
                            impresora11 = printService1;
                        }
                    }

                    if (impresora11 != null) {
                        printJob = impresora11.createPrintJob();
                        try {

                            printJob.print(document, attributeSet);
                        } catch (PrintException e) {
                            log.error("printExtra() {} ", e.getMessage());
                        }
                    } else {
                        log.error("No existen impresoras instaladas");
                        for (PrintService printService1 : printService) {
                            log.error(printService1.getName());
                        }

                    }

                    tex.close();
                }
            }
        }
    }

    private static String converteCaracter(String linha) throws IOException {
        String texto = "";

        //Ç     128    ×       158   +       188     +       218    °       248  
        //ü     129    ?       159   ¢       189     _       219    ¨       249  
        //é     130    á       160   ¥       190     _       220    ·       250  
        //â     131    í       161   +       191     ¦       221    ¹       251  
        //ä     132    ó       162   +       192     Ì       222    ³       252  
        //à     133    ú       163   -       193     _       223    ²       253  
        //å     134    ñ       164   -       194     Ó       224    _       254  
        //ç     135    Ñ       165   +       195     ß       225            255  
        //ê     136    ª       166   -       196     Ô       226  
        //ë     137    º       167   +       197     Ò       227  
        //è     138    ¿       168   ã       198     õ       228  
        //ï     139    ®       169   Ã       199     Õ       229  
        //î     140    ¬       170   +       200     µ       230  
        //ì     141    ½       171   +       201     Þ       231  
        //Ä     142    ¼       172   -       202     Þ       232  
        //Å     143    ¡       173   -       203     Ú       233  
        //É     144    «       174   ¦       204     Û       234  
        //æ       145    »       175   -       205     Ù       235  
        //Æ       146    _       176   +       206     ý       236  
        //ô       147    _       177   ¤       207     Ý       237  
        //ö       148    _       178   ð       208     ¯       238  
        //ò       149    ¦       179   Ð       209     ´       239  
        //û       150    ¦       180   Ê       210     ­       240  
        //ù       151    Á       181   Ë       211     ±       241  
        //ÿ       152    Â       182   È       212     _       242  
        //Ö       153    À       183   i       213     ¾       243  
        //Ü       154    ©       184   Í       214     ¶       244  
        //ø       155    ¦       185   Î       215     §       245  
        //£       156    ¦       186   Ï       216     ÷       246  
        //Ø       157    +       187   +       217     ¸       247}  
        for (Character c : linha.toCharArray()) {
            switch (c) {
                case 'á':
                    c = 'a';
                    break;
                case 'é':
                    c = 'e';
                    break;
                case 'í':
                    c = 'i';
                    break;
                case 'ó':
                    c = 'o';
                    break;
                case 'ú':
                    c = 'u';
                    break;
                case 'Á':
                    c = 'A';
                    break;
                case 'É':
                    c = 'E';
                    break;
                case 'Í':
                    c = 'I';
                    break;
                case 'Ó':
                    c = 'O';
                    break;
                case 'Ú':
                    c = 'U';
                    break;
                case 'ñ':
                    c = 'n';
                    break;
                case 'Ñ':
                    c = 'N';
                    break;
            }
            texto = (texto + c);
        }
        return texto;
    }

    /*
     * Metodo que imprime directamente en una impresra byte
     */
    public void printExtra(CexAgenda turno) throws IOException {
        //FileInputStream inputStream = null;
        InputStream tex = null;
        SimpleDateFormat sf = new SimpleDateFormat("dd/MM/yyyy");
        String fecha = sf.format(turno.getCagFecha());
        SimpleDateFormat sfHora = new SimpleDateFormat("HH:mm");
        String hora = "";
        String te2;
        if (turno.getCagHora() != null) {
            hora = sfHora.format(turno.getCagHora());
        }
        String impresora = "SIN IMPRESORA";
        PrintService impresora11 = null;
        try {
            //inputStream = new FileInputStream("e:/archivo.txt");

            String cadena = "************************************* \n\n"
                    + "RESPONSABLE: " + turno.getCagNombreUsuario() + " \n"
                    + "FECHA: " + fecha + " \n"
                    + turno.getCagNombreInstitucion() + "\n"
                    + turno.getCexHorariosDia().getCexHorario().getCexEspecialidadMedico().getCexEspecialidad().getCesNombre() + "\n"
                    + "HISTORIA CLINICA: " + turno.getCexHistoriaClinica().getChcHistoriaClinica() + "\n"
                    + "TURNO: " + turno.getCagSecuencia() + "\t HORA: " + hora + " \n"
                    + "MEDICO: " + turno.getCexHorariosDia().getCexHorario().getCexEspecialidadMedico().getAdmMedico().getAmeNombreFull() + "\n"
                    + "PACIENTE: " + turno.getCexHistoriaClinica().getChcNombreFull() + "\n"
                    + "*******   TURNO        EXTRA    ********\n"
                    + "\n"
                    + "\n"
                    + "SE RECOMIENDA ESTAR 30 MIN ANTES\n"
                    + " DE LA HORA ESPECIFICADA\n"
                    + "\n";
            te2 = converteCaracter(cadena);
            tex = new ByteArrayInputStream(te2.getBytes("UTF-8"));

        } catch (UnsupportedEncodingException e) {
            log.error("printExtra() {} ", e.getMessage());
        }
        if (tex == null) {
            return;
        }

        DocFlavor docFormat = DocFlavor.INPUT_STREAM.AUTOSENSE;
        Doc document = new SimpleDoc(tex, docFormat, null);

        PrintRequestAttributeSet attributeSet = new HashPrintRequestAttributeSet();

        for (AdmDatosGlobales datoGlobal : listaImpresorasturnos) {
            if (user.getIp().equals(datoGlobal.getClave())) {
                impresora = datoGlobal.getValor();
                break;
            }
        }
        // PrintService impresora11 = PrintServiceLookup.lookupDefaultPrintService();
        PrintService[] printService = PrintServiceLookup.lookupPrintServices(null, null);
        for (PrintService printService1 : printService) {
            if (printService1.getName().equals(impresora)) {
                impresora11 = printService1;
            }
        }

        if (impresora11 != null) {
            DocPrintJob printJob = impresora11.createPrintJob();
            try {
                printJob.print(document, attributeSet);
            } catch (PrintException e) {
                log.error("printExtra() {} ", e.getMessage());
            }
        } else {
            log.error("No existen impresoras instaladas");
        }

        tex.close();
    }

    public List<SelectItem> getSelectedItemProvincia() {
        try {
            List<AdmDivisionPolitica> datos = admin.listarNullOrdenada(AdmDivisionPolitica.class, "admDivisionPolitica", "nombre", true);
            List<SelectItem> items = new ArrayList<>();
            for (AdmDivisionPolitica obj : datos) {
                items.add(new SelectItem(obj, obj.getNombre()));
            }
            return items;
        } catch (Exception e) {
            log.error("getSelectedItemProvincia() {} ", e.getMessage());
        }
        return null;
    }

    public List<SelectItem> getSelectedItemCanton() {
        try {

            List<SelectItem> items = new ArrayList<>();
            for (AdmDivisionPolitica obj : provincia.getAdmDivisionPoliticaList()) {
                items.add(new SelectItem(obj, obj.getNombre()));
            }
            return items;
        } catch (Exception e) {
            log.error("getSelectedItemCanton() {} ", e.getMessage());
        }
        return null;
    }

    public List<SelectItem> getSelectedItemParroquia() {
        try {
            List<SelectItem> items = new ArrayList<>();
            for (AdmDivisionPolitica obj : canton.getAdmDivisionPoliticaList()) {
                items.add(new SelectItem(obj, obj.getNombre()));
            }
            return items;
        } catch (Exception e) {
            log.error("getSelectedItemParroquia() {} ", e.getMessage());
        }
        return null;
    }

    public void duplicarDireccion() {
        try {
            //////////////    hcHistoria.setHcDireccionReferencia(hcHistoria.getHcDireccion().trim());
        } catch (Exception e) {
            log.error("duplicarDireccion() {} ", e.getMessage());
        }

    }

    /**
     * Duplica el telefono del paciente con el telefono de la referencia
     * personal
     *
     */
    public void duplicarTelefono() {
        try {
            //////////////////////     hcHistoria.setHcRelefonoReferencia(hcHistoria.getHcTelefonoConv().trim());
        } catch (Exception e) {
            log.error("duplicarTelefono() {} ", e.getMessage());
        }

    }

    /**
     * Calcula la edad actual del paciente ingresado. parametro la fecha de
     * nacimiento
     */
    public void calcularEdad() {
        try {
            Calendar birth = new GregorianCalendar();
            Calendar today = new GregorianCalendar();
            SimpleDateFormat age = new SimpleDateFormat("dd-MM-yyyy");

            int factor = 0;
            String birthDate1 = age.format(hcHistoria.getChcFechaNacimiento());
            Date birthDate = new SimpleDateFormat("dd-MM-yyyy").parse(birthDate1);
            Date currentDate = new Date();
            birth.setTime(birthDate);
            today.setTime(currentDate);
            if (today.get(Calendar.MONTH) <= birth.get(Calendar.MONTH)) {
                if (today.get(Calendar.MONTH) == birth.get(Calendar.MONTH)) {
                    if (today.get(Calendar.DATE) > birth.get(Calendar.DATE)) {
                        factor = -1; //Aun no celebra su cumpleaÃ±os
                    }
                } else {
                    factor = -1; //Aun no celebra su cumpleaÃ±os
                }
            }
            hcHistoria.setChcEdad((today.get(Calendar.YEAR) - birth.get(Calendar.YEAR)) + factor);

        } catch (ParseException e) {
            log.error("calcularEdad {}: {} ", e);

        }

    }

    public void validarCedula() {
        FacesContext context = FacesContext.getCurrentInstance();
        if (Aplinfo.isRucCedulaValido(hcHistoria.getChcCedula()) == false) {
            //FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "cedula").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Cédula incorrecta", "Cédula incorrecta"));
            cadulaInc = 1;
        } else {
            cadulaInc = 0;
        }
    }

    /**
     * Actualiza los datos de la historia clinica en el caso de estar
     * incompletos
     *
     *
     * @author David Carranza
     */
    public void actualizarHc() {
        FacesContext context = FacesContext.getCurrentInstance();
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "()";
        try {
            //GetMax de la historia clinica

            cadulaInc = 0;
            Integer cedRepetida = 0;
            hcHistoria.setChcPrimerNombre(hcHistoria.getChcPrimerNombre().toUpperCase().trim());
            hcHistoria.setChcSegundoNombre(hcHistoria.getChcSegundoNombre().toUpperCase().trim());
            hcHistoria.setChcApellidoPaterno(hcHistoria.getChcApellidoPaterno().toUpperCase().trim());
            hcHistoria.setChcApellidoMaterno(hcHistoria.getChcApellidoMaterno().toUpperCase().trim());
            //hcHistoria.setChcNombrePadre(hcHistoria.getChcNombrePadre().toUpperCase().trim());
            //hcHistoria.setChcNombreMadre(hcHistoria.getChcNombreMadre().toUpperCase().trim());
            hcHistoria.setChcNombreFull(hcHistoria.getChcApellidoPaterno().toUpperCase().concat(" ").concat(hcHistoria.getChcApellidoMaterno().toUpperCase().concat(" ").concat(hcHistoria.getChcPrimerNombre().toUpperCase().concat(" ").concat(hcHistoria.getChcSegundoNombre().toUpperCase()))));
            hcHistoria.setChcBarrio(hcHistoria.getChcBarrio().toUpperCase().trim());
            hcHistoria.setChcLugarNacimiento(hcHistoria.getChcLugarNacimiento().toUpperCase().trim());
            hcHistoria.setChcInstruccion(hcHistoria.getChcInstruccion().toUpperCase().trim());
            hcHistoria.setChcOcupacion(hcHistoria.getChcOcupacion().toUpperCase().trim());
            hcHistoria.setChcNombreEmpresa(hcHistoria.getChcNombreEmpresa().toUpperCase().trim());
            hcHistoria.setChcReferido(hcHistoria.getChcReferido().toUpperCase().trim());
            hcHistoria.setChcNombreReferencia(hcHistoria.getChcNombreReferencia().toUpperCase().trim());
            hcHistoria.setAdmDivisionPolitica(parroquia);
            hcHistoria.setChcIdInstitucion(user.getUser().getAdmEmpleado().getAdmInstitucion().getIdInstitucion());
            hcHistoria.setChcNombreInstitucion(user.getUser().getAdmEmpleado().getAdmInstitucion().getNombre());
            hcHistoria.setChcIdInstitucionSistema(user.getUser().getAdmEmpleado().getAdmInstitucion().getAdmInstitucionSistema().getIdInstitucionSistema());
            hcHistoria.setChcNombreInstitucionSistema(user.getUser().getAdmEmpleado().getAdmInstitucion().getAdmInstitucionSistema().getNombre());
            hcHistoria.setChcDireccionReferencia(hcHistoria.getChcDireccionReferencia().toUpperCase().trim());
            hcHistoria.setChcTipoIngreso(1);

            if (habilitar.equals(false)) {
                hcHistoria.setChcCedula("");
            } else {
                hcHistoria.setChcPasaporte("");
                validarCedula();
                try {
                    if (hcHistoria.getChcId() == null) {
                        hcHistoria.setChcEstado(1);
                        //Codigos que vienen de la isntitucion donde saco la historia clinica
                        //Verifico si la institucion tiene distrito caso copntratio se debe poner division politica
                        hcHistoria.setChcDipCodigoProvincia(user.getUser().getAdmEmpleado().getAdmInstitucion().getAdmDivisionPolitica().getAdmDivisionPolitica().getAdmDivisionPolitica().getCodigo());
                        hcHistoria.setChcDipCodigoCanton(user.getUser().getAdmEmpleado().getAdmInstitucion().getAdmDivisionPolitica().getAdmDivisionPolitica().getCodigo());
                        hcHistoria.setChcDipCodigoParroquia(user.getUser().getAdmEmpleado().getAdmInstitucion().getAdmDivisionPolitica().getCodigo());
                        //hcHistoria.setChcTipoIngreso(1);
                        hcHistoria.setChcNombreParroquia(user.getUser().getAdmEmpleado().getAdmInstitucion().getAdmDivisionPolitica().getNombre());
                        hcHistoria.setChcNombreCanton(user.getUser().getAdmEmpleado().getAdmInstitucion().getAdmDivisionPolitica().getAdmDivisionPolitica().getNombre());
                        hcHistoria.setChcNombreProvincia(user.getUser().getAdmEmpleado().getAdmInstitucion().getAdmDivisionPolitica().getAdmDivisionPolitica().getAdmDivisionPolitica().getNombre());
                        hcHistoria.setChcNombreDistrito("17D03| - PUELLARO, CHAVEZPAMBA, ATAHUALPA, S.J MINAS, PERUCHO, EL CONDADO, PONCEANO, SAN ANTONIO, NONO, COTOCOLLAO, POMASQUI, CALACALI, COMITE DEL PUEBLO, CARCELEN");
                        hcHistoria.setChcIdUsuario(user.getUser().getIdUsuario().intValue());
                        hcHistoria.setChcNombreUsuario(user.getUser().getAdmEmpleado().getNombreFull());

                        if (admin.existePorCampo(CexHistoriaClinica.class, "chcCedula", hcHistoria.getChcCedula())) {
                            FacesContext.getCurrentInstance()
                                    .addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Cédula ya existe", "Cédula ya existe"));

                            return;
                        } else {
                            cedRepetida = 0;
                        }
                    }
                } catch (Exception e) {
                    log.error("Verificar si existe cedula repetida() {} ", e.getMessage());
                    FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), e.getMessage()));
                }
            }

            if (cadulaInc == 1) {
                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "cedula").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Cédula incorrecta", "Cédula incorrecta"));

            } else {
                if (hcHistoria.getChcId() == null) {
                    if (cedRepetida == 0) {
                        try {
                            Integer hcMax = new Integer((String) admin.getMax(CexHistoriaClinica.class, "chcHistoriaClinica")) + 1;
                            hcHistoria.setChcHistoriaClinica(hcMax.toString());
                            hcHistoria.setChcEstado(1);
                            //Codigos que vienen de la isntitucion donde saco la historia clinica
                            //Verifico si la institucion tiene distrito caso copntratio se debe poner division politica
                            hcHistoria.setChcDipCodigoProvincia(user.getUser().getAdmEmpleado().getAdmInstitucion().getAdmDivisionPolitica().getAdmDivisionPolitica().getAdmDivisionPolitica().getCodigo());
                            hcHistoria.setChcDipCodigoCanton(user.getUser().getAdmEmpleado().getAdmInstitucion().getAdmDivisionPolitica().getAdmDivisionPolitica().getCodigo());
                            hcHistoria.setChcDipCodigoParroquia(user.getUser().getAdmEmpleado().getAdmInstitucion().getAdmDivisionPolitica().getCodigo());
                            //hcHistoria.setChcTipoIngreso(1);
                            hcHistoria.setChcNombreParroquia(user.getUser().getAdmEmpleado().getAdmInstitucion().getAdmDivisionPolitica().getNombre());
                            hcHistoria.setChcNombreCanton(user.getUser().getAdmEmpleado().getAdmInstitucion().getAdmDivisionPolitica().getAdmDivisionPolitica().getNombre());
                            hcHistoria.setChcNombreProvincia(user.getUser().getAdmEmpleado().getAdmInstitucion().getAdmDivisionPolitica().getAdmDivisionPolitica().getAdmDivisionPolitica().getNombre());
                            hcHistoria.setChcNombreDistrito("17D03| - PUELLARO, CHAVEZPAMBA, ATAHUALPA, S.J MINAS, PERUCHO, EL CONDADO, PONCEANO, SAN ANTONIO, NONO, COTOCOLLAO, POMASQUI, CALACALI, COMITE DEL PUEBLO, CARCELEN");
                            hcHistoria.setChcIdUsuario(user.getUser().getIdUsuario().intValue());
                            hcHistoria.setChcNombreUsuario(user.getUser().getAdmEmpleado().getNombreFull());

                            if (!admin.existePorCampo(CexHistoriaClinica.class, "chcHistoriaClinica", hcHistoria.getChcHistoriaClinica())) {
                                admin.crear(hcHistoria, (UsuarioAdmin) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user"));
                                //inicializar();
                                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(bundle.getString("msg.grabar")));
                            } else {
                                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Historia clínica ya existe", "Historia clínica ya existe"));
                            }

                        } catch (Exception e) {
                            log.error("grabarAction() {} ", e.getMessage());
                            FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), e.getMessage()));
                        }
                    }
                } else {
                    try {
                        if (activo) {
                            hcHistoria.setChcEstado(1);
                        } else {
                            hcHistoria.setChcEstado(0);
                        }
                        admin.modificar(hcHistoria, (UsuarioAdmin) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user"));
                        //inicializar();
                        FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(bundle.getString("msg.actualizar")));
                    } catch (Exception e) {
                        log.error("grabarAction() {} ", e.getMessage());
                        FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), e.getMessage()));
                    }
                }
                agenda.setCexHistoriaClinica(hcHistoria);
                hcHistoria = new CexHistoriaClinica();
                provincia = new AdmDivisionPolitica();
                canton = new AdmDivisionPolitica();
                parroquia = new AdmDivisionPolitica();
            }
        } catch (Exception e) {
            log.error("{}: {} ", nombreMetodo, e);
        }

    }

    /**
     * Actualiza los datos de la historia clinica en el caso de estar
     * incompletos
     *
     *
     * @author David Carranza
     */
    public void nuevaHc() {
        agenda = new CexAgenda();
        hcHistoria = new CexHistoriaClinica();
    }

    /**
     * Metodo que busca segun la especialidad , el Doctor el turno vacio mas
     * proximo
     *
     */
    public void buscarSiguienteTurno() {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "()";
        try {
            crearDetallefechaSumada();
            cargarHorario();
        } catch (Exception e) {
            log.error("{}: {} ", nombreMetodo, e);
        }

    }

    /**
     * Metodo crea agenda y detalkle en las fechas sumadas
     *
     */
    public void crearDetallefechaSumada() {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "()";
        //Lazo principal mientras el contador sea 0
        try {
            int cont = 0;
            int contTurnos = 0;
            boolean isContLibre = false;
            Date fechaTemporal = fechaAgenda;
            Date fechaSumada = fechaTemporal;
            boolean isSelected = false;
            int nuevaSecuencia = 0;
            Calendar horaSumada = new GregorianCalendar();
            Calendar cal = new GregorianCalendar();
            int cont1 = 1;
            listaHorarioDia.clear();
            listaAgenda.clear();
            while (cont == 0) {
                listaAgenda.clear();
                listaHorarioDia.clear();
                //sumar un dia a la fecha actual hasta que encuentre dia disponible
                cal.setTime(fechaSumada);
                cal.add(Calendar.DATE, 1);
                fechaSumada = cal.getTime();
                Integer diatEMP = cal.get(Calendar.DAY_OF_WEEK);
                fechaAgenda = cal.getTime();

                //Recupera permiso para saber si se puede agendar en la fecha seleccionada
                List<AdmPermiso> objLicencia = (List<AdmPermiso>) adminObject.queryEJB("select p from AdmPermiso p where :var1 between p.apeFechaInicio and p.apeFechaFin and p.admMedico = :var2", fechaAgenda, object.getAdmMedico());
                if (objLicencia.size() > 0 || !objLicencia.isEmpty()) {
                    continue;
                }

                //Caso importante si existe la agenda creada 
                //Recuper la lista del horario de acuerdo al dia seleciconado
                for (CexHorario objTemH : object.getCexHorarioList()) {
                    //Agregar horario de acuerdo a la fecha
                    if ((fechaAgenda.after(objTemH.getChoFechaInicio()) || objTemH.getChoFechaInicio().equals(fechaAgenda))
                            && (fechaAgenda.before(objTemH.getChoFechaFin()) || objTemH.getChoFechaFin().equals(fechaAgenda))) {
                        //Verificar los horarios segun el tipo de consulta de la agenda
                        if (objTemH.getAdmTipoConsulta().equals(admTipoConsulta)) {
                            //Recorrer los horarios dias de cada horario
                            for (CexHorariosDia objTemHd : objTemH.getCexHorariosDiaList()) {
                                if (objTemHd.getCexDia().getCdiId().equals(diatEMP)) {
                                    //Añadir solo el horario que tenga asignado hora inicio y hora fin
                                    if (objTemHd.getChdHoraInicioAm() != null && objTemHd.getChdHoraFinAm() != null) {
                                        listaHorarioDia.add(objTemHd);
                                    }
                                }
                            }
                        }
                    }
                }

                //Veriica que existe horarios asignados de acuerdo al dia de la fecha sumada
                if (listaHorarioDia.isEmpty() || listaHorarioDia.size() <= 0) {
                    continue;
                }

                //Hace un select a la base de datos para obtener la agenda del dia seleccionado
                listarturnos(fechaSumada, 0);

                //verifica si la agenda esta o no crea en el dia seleccioando
                if (listaAgenda.isEmpty() || listaAgenda.size() <= 0) {
                    cont1 = 1;
                    for (CexHorariosDia horDia : listaHorarioDia) {
                        if (horDia.getOrdenHorario() > 0) {
                            cont1 = cont1 + listaHorarioDia.get(horDia.getOrdenHorario() - 1).getChdNumConsultas();
                        }
                        crearDetalle(fechaSumada, horDia, cont1);
                    }
                    isSelected = true;
                    isContLibre = true;
                } else {
                    // Comprobar si el numero de turnos es mayor o igual al numero asignado en los horarios del medico
                    // esto mas en el caso de los turnos migrados
                    for (CexHorariosDia objHorDi : listaHorarioDia) {
                        nuevaSecuencia = 0;
                        contTurnos = 0;
                        isContLibre = false;
                        for (CexAgenda cexAgetemp1 : listaAgenda) {

                            //Recorrer segun el numero de horarioDia
                            if (objHorDi.getOrdenHorario() == cexAgetemp1.getNumeroHorario()) {
                                if (cexAgetemp1.getCagTipo() == 0 || cexAgetemp1.getCagTipo() == 1 || cexAgetemp1.getCagTipo() == 3) {
                                    nuevaSecuencia++;
                                    contTurnos++;
                                }

                                if (cexAgetemp1.getCagEstado() == 0 && cexAgetemp1.getCagTipo() == 0) {
                                    isContLibre = true;
                                }
                            }

                        }

                        //Verificar Numero de turnos para agregar o quitar turnos
                        if (objHorDi.getChdNumConsultas() > contTurnos) {
                            //Se crea los turnos restantes 
                            int turnosRest = objHorDi.getChdNumConsultas() - contTurnos;
                            //Calcular la Hora
                            //Calcular los tiempos para cada turno
                            horaInicioAm.setTime(objHorDi.getChdHoraInicioAm());
                            horaFinAm.setTime(objHorDi.getChdHoraFinAm());
                            long iniAm = horaInicioAm.getTimeInMillis();
                            long finAm = horaFinAm.getTimeInMillis();
                            //calcular total de minitos al dia asignado al medico
                            long totHoras = (finAm - iniAm);

                            // calcular la diferencia en milisengundos
                            //long diff = milis2 - milis1;
                            // calcular la diferencia en segundos
                            //long diffSeconds = diff / 1000;
                            // calcular la diferencia en minutos
                            diffMinutes = totHoras / (60 * 1000);

                            // calcular la diferencia en horas
                            //long diffHours = diff / (60 * 60 * 1000);
                            // calcular la diferencia en dias
                            //long diffDays = diff / (24 * 60 * 60 * 1000);
                            rangoMuinutos = divisionControlada(new BigDecimal(diffMinutes), new BigDecimal(objHorDi.getChdNumConsultas()));
                            rangoMuinutos = rangoMuinutos.setScale(0, RoundingMode.HALF_UP);
                            //Asignar hora ultima
                            horaSumada.setTime(objHorDi.getCexAgendaList().get(objHorDi.getCexAgendaList().size() - 1).getCagHora());

                            for (int i = 1; i <= turnosRest; i++) {
                                agenda.setCagTipo(0);
                                agenda.setCagSecuencia(nuevaSecuencia + 1);
                                agenda.setCexHorariosDia(objHorDi);
                                agenda.setCagEstado(0);
                                agenda.setCexHistoriaClinica(null);
                                agenda.setCagFecha(fechaAgenda);
                                horaSumada.add(Calendar.MINUTE, rangoMuinutos.intValue());
                                agenda.setCagHora(horaSumada.getTime());
                                adminObject.crear(agenda, (UsuarioAdmin) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user"));
                                agenda = new CexAgenda();
                                isSelected = true;
                                nuevaSecuencia++;
                                //sacar la lista de detalle
                            }
                        } else {
                            //caso contrario elimina los turnos que estan demas en el nuevo horario
                            if (objHorDi.getChdNumConsultas() < contTurnos) {
                                // Se crea los turnos restantes que no esten asignados turnos
                                //los que esten quedan visibles para reasignar
                                int cont2 = 0;
                                int turnosEliminar = contTurnos - objHorDi.getChdNumConsultas();
                                for (CexAgenda cexAgendaTemp : listaAgenda) {
                                    if (cexAgendaTemp.getNumeroHorario() == objHorDi.getOrdenHorario()) {
                                        if (cont2 != turnosEliminar) {
                                            if (cexAgendaTemp.getCexHistoriaClinica() == null) {
                                                adminObject.eliminar(cexAgendaTemp, (UsuarioAdmin) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user"));
                                                cont2++;
                                                isSelected = true;
                                            }
                                        }
                                    }

                                }
                            }
                        }
                    }
                }

                if (isContLibre) {
                    cont = 1;
                }

            }

            if (isSelected) {
                //Limpia la lista originay y carga los nuevos valores 
                //Recuperar las agendas de acuerdo al horarioDia y de acuerdo a las fechas
                listarturnos(fechaSumada, 0);
            }

        } catch (Exception e) {
            log.error("{}: {} ", nombreMetodo, e);
        }
    }

    /**
     * Metodo que lista los turnos de la tarde si esta activo caso contrario
     * lista todos olos turnos
     *
     * @author David bjTemHor
     * @param fechaTemp
     * @param cont
     */
    public void listarturnos(Date fechaTemp, int cont) {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "()";
        try {
            List<CexAgenda> listTempAgen;
            listaAgenda.clear();
            for (CexHorariosDia objHorDia : listaHorarioDia) {
                //Asignar numero de horario
                objHorDia.setOrdenHorario(cont);
                listTempAgen = adminObject.listarOrdenada(CexAgenda.class, "cagFecha", fechaTemp, "cexHorariosDia", objHorDia, "cagSecuencia", true);
                for (CexAgenda objA : listTempAgen) {
                    objA.setNumeroHorario(cont);
                    listaAgenda.add(objA);
                }
                listTempAgen.clear();
                cont++;
            }
        } catch (Exception e) {
            log.error("{}: {} ", nombreMetodo, e);
        }
    }

    @Override
    public DataModel<CexEspecialidadMedico> getDataModel() {
        return null;
    }

    public CexEspecialidad getEspecialidad() {
        return especialidad;
    }

    public CexHistoriaClinica getCexHistoriaClinica() {
        return hcPaciente;
    }

    public void setCexHistoriaClinica(CexHistoriaClinica hcPaciente) {
        this.hcPaciente = hcPaciente;
    }

    public void setEspecialidad(CexEspecialidad especialidad) {
        this.especialidad = especialidad;
    }

    public CexEspecialidad getSubEspecialidad() {
        return subEspecialidad;
    }

    public void setSubEspecialidad(CexEspecialidad subEspecialidad) {
        this.subEspecialidad = subEspecialidad;
    }

    public Integer getBusqueda() {
        return busqueda;
    }

    public void setBusqueda(Integer busqueda) {
        this.busqueda = busqueda;
    }

    public Integer getTipoBusqueda() {
        return tipoBusqueda;
    }

    public void setTipoBusqueda(Integer tipoBusqueda) {
        this.tipoBusqueda = tipoBusqueda;
    }

    public String getParametroBusqueda() {
        return parametroBusqueda;
    }

    public void setParametroBusqueda(String parametroBusqueda) {
        this.parametroBusqueda = parametroBusqueda;
    }

    public String getApellidoPbusqueda() {
        return apellidoPbusqueda;
    }

    public void setApellidoPbusqueda(String apellidoPbusqueda) {
        this.apellidoPbusqueda = apellidoPbusqueda;
    }

    public String getApellidoMbusqueda() {
        return apellidoMbusqueda;
    }

    public void setApellidoMbusqueda(String apellidoMbusqueda) {
        this.apellidoMbusqueda = apellidoMbusqueda;
    }

    public String getpnombrebusqueda() {
        return pnombrebusqueda;
    }

    public String getPnombrebusqueda() {
        return pnombrebusqueda;
    }

    public void setPnombrebusqueda(String pnombrebusqueda) {
        this.pnombrebusqueda = pnombrebusqueda;
    }

    public String getSnombrePbusqueda() {
        return snombrePbusqueda;
    }

    public void setSnombrePbusqueda(String snombrePbusqueda) {
        this.snombrePbusqueda = snombrePbusqueda;
    }

    public List<CexHistoriaClinica> getListaHClinica() {
        return listaHClinica;
    }

    public void setListaHClinica(List<CexHistoriaClinica> listaHClinica) {
        this.listaHClinica = listaHClinica;
    }

    public CexAgenda getAgenda() {
        return agenda;
    }

    public void setAgenda(CexAgenda agenda) {
        this.agenda = agenda;
    }

    public Date getFechaAgenda() {
        return fechaAgenda;
    }

    public void setFechaAgenda(Date fechaAgenda) {
        this.fechaAgenda = fechaAgenda;
    }

    public List<CexHorario> getListaHorarioMed() {
        return listaHorarioMed;
    }

    public void setListaHorarioMed(List<CexHorario> listaHorarioMed) {
        this.listaHorarioMed = listaHorarioMed;
    }

    public AdmDivisionPolitica getProvincia() {
        return provincia;
    }

    public void setProvincia(AdmDivisionPolitica provincia) {
        this.provincia = provincia;
    }

    public AdmDivisionPolitica getCanton() {
        return canton;
    }

    public void setCanton(AdmDivisionPolitica canton) {
        this.canton = canton;
    }

    public AdmDivisionPolitica getParroquia() {
        return parroquia;
    }

    public void setParroquia(AdmDivisionPolitica parroquia) {
        this.parroquia = parroquia;
    }

    public CexHistoriaClinica getHcHistoria() {
        return hcHistoria;
    }

    public void setHcHistoria(CexHistoriaClinica hcHistoria) {
        this.hcHistoria = hcHistoria;
    }

    public Boolean getHabilitar() {
        return habilitar;
    }

    public void setHabilitar(Boolean habilitar) {
        this.habilitar = habilitar;
    }

    public boolean isActivo() {
        return activo;
    }

    public void setActivo(boolean activo) {
        this.activo = activo;
    }

    public boolean isIsextra() {
        return isextra;
    }

    public void setIsextra(boolean isextra) {
        this.isextra = isextra;
    }

    public List<CexAgenda> getListaHistorialTurnos() {
        return listaHistorialTurnos;
    }

    public void setListaHistorialTurnos(List<CexAgenda> listaHistorialTurnos) {
        this.listaHistorialTurnos = listaHistorialTurnos;
    }

    public boolean isIsGrabar() {
        return isGrabar;
    }

    public void setIsGrabar(boolean isGrabar) {
        this.isGrabar = isGrabar;
    }

    public AdmUsuario getAdmUsuario() {
        return admUsuario;
    }

    public void setAdmUsuario(AdmUsuario admUsuario) {
        this.admUsuario = admUsuario;
    }

    public List<CexDia> getListaDia() {
        return listaDia;
    }

    public void setListaDia(List<CexDia> listaDia) {
        this.listaDia = listaDia;
    }

    public String getMotivoBloqueo() {
        return motivoBloqueo;
    }

    public void setMotivoBloqueo(String motivoBloqueo) {
        this.motivoBloqueo = motivoBloqueo;
    }

    public List<CexAgenda> getListaAgenda() {
        return listaAgenda;
    }

    public void setListaAgenda(List<CexAgenda> listaAgenda) {
        this.listaAgenda = listaAgenda;
    }

    public Date getHoraTurnoExtra() {
        return horaTurnoExtra;
    }

    public void setHoraTurnoExtra(Date horaTurnoExtra) {
        this.horaTurnoExtra = horaTurnoExtra;
    }

    public String getMotivoCancelar() {
        return motivoCancelar;
    }

    public void setMotivoCancelar(String motivoCancelar) {
        this.motivoCancelar = motivoCancelar;
    }

    public UsuarioAdmin getUser() {
        return user;
    }

    public void setUser(UsuarioAdmin user) {
        this.user = user;
    }

    @Override
    protected ResourceBundle getProperties() {
        return ResourceBundle.getBundle("aplicacion");
    }
}
